您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 薪酬管理 > JavaScript是一种面向对象的脚本语言
JavaScript是一种面向对象的脚本语言,但是JavaScript中的对象与其他语言(尤其是像Java、C#这样的静态语言)有很大的不同,JavaScript中的对象是基于原型的。原型是对象的基础,它定义并实现了一个新对象所必须包含的成员列表,并被所有同类对象实例所共享。与其他语言中类的概念相比,原型更像是类的静态成员。本文就JavaScript中对象的创建、继承做初步的讲解,并探讨下对象成员相关的一些概念和特性。(斑头雁原创:)一、创建对象在JavaScript使用new操作符中创建对象,或者用直接量创建对象。与其他语言不同,JavaScript对象在完成创建后仍能增加成员,比如如下的代码:Js代码1.varobj=newObject();2.obj.name='alice';3.obj.age=18;4.obj.getSalary=function(){return8000-this.age;};这段代码首先创建了一个Object类的对象,然后增加了三个成员。除了用new操作符创建对象外,我们还可以用直接量表示一个对象,如下面的代码:Js代码1.varobj={2.name:'alice',3.age:18,4.getSalary:function(){return8000-this.age;}5.};这段代码创建了一个对象,与前面代码创建的对象一样,但是相比较起来,用直接量方式更加简单明了。(斑头雁原创:)二、创建类除了可以使用JavaScript内建的类外,我们还可以定义自己的类,定义类的方法一般有工厂方法、构造函数、原型方法和混合方法。1、工厂方法创建对象的传统方式是首先创建一个Object实例,然后增加成员属性,如果把这些代码用一个函数封装起来并返回所创建的对象,那这个函数就是创建对象的工厂函数。使用工厂函数的示例代码如下:Js代码1.functionpgetSalary(){return8000-this.age;}2.functionEmployee(name,age){3.varobj=newObject();4.obj.name=name;5.obj.age=age;6.obj.getSalary=pgetSalary;7.8.returnobj;9.}10.varobja=Employee('alice',18);11.varobjb=newEmployee('cindy',20,true);12.alert(objainstanceofEmployee);//outputfalse采用工厂方式可以方便的创建大批量类似对象,但是工厂函数的名字并不是类的名字,虽然可以用new操作符,但仍无法使用instanceof来判断所创建的对象的类型。另外,如果把成员函数的函数体定义在工厂函数的内部的话,创建对象时会重复的创建成员函数实例(在JavaScript中函数也是一种对象),浪费存储空间。(斑头雁原创:)2、构造函数方法构造函数类似工厂函数,所不同的是构造函数的名字就是类名,可以用new操作符来创建对象。Js代码1.functionpgetSalary(){return8000-this.age;}2.functionEmployee(name,age){3.this.name=name;4.this.age=age;5.this.getSalary=pgetSalary;6.}7.varobja=newEmployee('alice',18);8.varobjb=newEmployee('cindy',19);9.alert(objainstanceofEmployee);//outputtrue同工厂方式一样,如果类有成员函数,最好定义在构造函数意外,否则会因成员函数的重复创建而浪费空间。用构造函数创建对象的好处是所生成的对象可以用instanceof来判断所属的类。(斑头雁原创:)3、原型方法原型是对象的模板,所以我们可以用prototype属性来定义一个类,通常的做法是定义一个空的构造函数,然后在prototype属性上定义类的成员,示例代码如下:Js代码1.functionEmployee(){2.}3.Employee.prototype.name='alice';4.Employee.prototype.age=18;5.Employee.prototype.getSalary=function(){return8000-this.age;};6.Employee.prototype.languages=['Java','C#'];7.8.varobja=newEmployee();9.varobjb=newEmployee();10.alert(objainstanceofEmployee);//outputtrue11.alert(obja.languages);//outputJava,C#12.alert(objb.languages);//outputJava,C#13.objb.languages.push('perl');14.varobjc=newEmployee();15.alert(obja.languages);//outputJava,C#,perl16.alert(objb.languages);//outputJava,C#,perl17.alert(objc.languages);//outputJava,C#,perl原型方式同构造函数方式一样可以用instanceof判断所创建的对象的类型,但是,原型方式的构造函数不能带任何参数,除此之外,如果某个成员是一个对象实例,那么对这个成员的修改可能会影响到这个类创建的其他对象以及在此之后创建的对象。如示例代码中仅修改了对象objb的languages属性,而在此之前创建的obja与在此之后创建的objc的languages属性也受到了影响。(斑头雁原创:)4、混合方式(构造函数+原型)原型方式的构造函数不能带有参数,这样的类在使用中显得很不方便,因此,把原型方式与构造函数综合起来使用是一种更为实用的方法,示例代码如下:Js代码1.functionEmployee(name,age){2.this.name=name;3.this.age=age;4.this.languages=['Java','C#'];5.}6.Employee.prototype.getSalary=function(){return8000-this.age;};7.varobja=newEmployee('alice',18);8.varobjb=newEmployee('cindy',20);9.alert(obja.languages);//outputJava,C#10.alert(objb.languages);//outputJava,C#11.objb.languages.push('perl');12.varobjc=newEmployee();13.alert(obja.languages);//outputJava,C#14.alert(objb.languages);//outputJava,C#,perl15.alert(objc.languages);//outputJava,C#混合方式利用构造函数定义非函数成员,用prototype定义函数成员,既避免了因重复创建成员函数造成的空间浪费,又不会造成对象实例间的相互影响(如示例代码中修改objb的languages成员不会影响到obja和objc),是一种比较好的定义类的方式。(斑头雁原创:)三、类的继承JavaScript根本就没有继承类的机制,不过借助JavaScript的一些语言特性,我们仍然可以模拟这种行为,常用的方法有对象冒充、原型链和混合方式。(斑头雁原创:)1、对象冒充JavaScript函数中this会根据函数的调用上下文的不同指向不同的对象,根据这个特性,开发者总结出了对象冒充方式的继承方法,示例代码如下:Js代码1.functionEmployee(name,age){2.this.name=name;3.this.age=age;4.this.languages=['Java','C#'];5.}6.Employee.prototype.getSalary=function(){return8000-this.age;};7.8.functionManager(name,age,level){9.Employee.call(this,name,age);10.//Employee.apply(this,[name,age]);11.this.level=level;12.}13.14.varma=newManager('alice',18,1);15.alert(mainstanceofEmployee);//outputfalse16.alert(mainstanceofManager);//outputtrue17.alert(ma.name);//outputalice18.alert('getSalary'inma);//outputfalseFucntion.call()与Fucntion.apply()会执行函数Function本身,只不这两个方法的第一个参数都是用来代替Function内部的this,这两个函数所不同的地方在于call把Function的参数顺序放在第一个参数之后,apply把Function的参数按顺序组成一个数组作为第二个参数调用。在示例代码中,构造函数Manager调用了Employee的call方法,所以执行嵌套的Employee时内部的this指向的是Manager的this,这样用Manager创建的对象就有了Employee的成员。对象冒充方式继承有一个好处就是可以实现多继承,像下面的代码就可以实现多继承。Js代码1.functionClassC(){2.ClassA.call(this);3.ClassB.call(this);4.}如果ClassA与ClassB有相同名字的成员,那么会因为调用顺序导致ClassB的成员定义会覆盖ClassA的成员定义,这在使用时要加以注意。对象冒充继承方式的问题在于它无法使用instanceof来判断对象是不是超类的实例,另外也无法继承定义在超类prototype属性上的成员(如示例代码中的成员函数getSalary么有被类Manager继承)。(斑头雁原创:)2、原型链原型链继承与用原型方式创建类一样,方法是构造一个空构造函数,然后用超类的实例代替子类的prototype,示例代码如下:Js代码1.functionEmployee(name,age){2.this.name=name;3.this.age=age;4.this.languages=['Java','C#'];5.}6.Employee.prototype.getSalary=function(){return8000-this.age;};7.8.functionManager(){9.}10.Manager.prototype=newEmployee();11.12.varma=newManager();13.alert(mainstanceofEmployee);//outputtrue14.alert(mainstanceofManager);//outputtr
本文标题:JavaScript是一种面向对象的脚本语言
链接地址:https://www.777doc.com/doc-3650464 .html