1.对象冒泡
关键字this引用的是构造函数当前创建的对象,不过在这个方法中,this指向的是所属的对象把ClassA作为常规的函数来建立继承机制。
1 function ClassA(sColor) 2 { 3 this.color=sColor; 4 this.sayColor=function(){ 5 alert(this.color); 6 }; 7 } 8 9 10 11 function ClassB(sColor){ 12 this.newMethod=ClassA; 13 this.newMethod(sColor); 14 delete this.newMethod; 15 16 this.name=sName; 17 this.sayName=function(){ 18 alert(this.name); 19 }; 20 } 21 22 23 var objA=new ClassA("red"); 24 var objB=new ClassB("blue","Nicholas"); 25 objA.sayColor(); //outputs "red" 26 objB.sayColor(); //outputs "blue" 27 objB.sayName(); //outputs "Nicholas"
2.Call()方法
call()方法的第一个参数用作this的对象,制定方法内部的this指向。
1 function ClassB(sColor,sName){ 2 ClassA.call(this,sColor); 3 4 5 this.name=sName; 6 this.sayName=function(){ 7 alert(this.name); 8 }; 9 }
3.Apply()方法
apply()方法与call()方法非常类似,只是第二个参数传递的是数组对象。
1 function ClassB(sColor,sName){ 2 ClassA.apply(this,new Array(sColor)); 3 4 5 this.name=sName; 6 this.sayName=function(){ 7 alert(this.name); 8 }; 9 }
同样的,第一个参数仍然为this,第二个参数是只有一个值color的数组。可以把ClassB的整个arguments对象作为第二个参数传递给apply()方法。
1 function ClassB(sColor,sName){ 2 ClassA.apply(this,arguments); 3 4 5 this.name=sName; 6 this.sayName=function(){ 7 alert(this.name); 8 }; 9 }
当然,只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象,如果不一致就要创建一个数组对象,按照正确的顺序放置参数。
4.原型链
1 function ClassA{} 2 3 ClassA.prototype.color="red"; 4 ClassA.prototype.sayColor=function() 5 { 6 alert(this.color); 7 }; 8 9 function ClassB(){ 10 } 11 12 ClassB.prototype=new ClassA(); 13 ClassB.prototype.name="'; 14 ClassB.prototype.sayName=function() 15 { alert(this.name); 16 17 }; 18 19 20 var objA=new ClassA(); 21 var objB=new ClassB(); 22 objA.color="red"; 23 objB.color="blue'; 24 objB.name="Nicholas"; 25 objA.sayColor(); 26 objB.sayColor(); 27 objB.sayName();
调用ClassA的构造函数时,没有给他传递参数,这在原型链中是标准的做法,要确保构造函数没有任何参数。所有的prototype属性赋值都必须出现在prototype属性被赋值之后,因为在它之前赋值的所有方法都会被删除。因为prototype属性被替换成了新的对象。所以为ClassB类添加name属性和sayName的方法代码如下:
1 function ClassB(){} 2 3 ClassB.prototype=new ClassA(); 4 ClassB。prototype.name=""; 5 ClassB.prototype.sayName=function(){ 6 alert(this.name); 7 8 };
5混合方式
对象冒泡的方式主要问题是必须使用构造函数方式,上面学过这不是最好的方式。不过如果使用原型链的方式,就无法使用带参数的构造函数。最好的方式是,用构造函数方式定义属性,用原型方式定义方法,这同样适合继承机制,用对象冒充继承构造函数的属性,用原型链继承prototype的方法。
1 function ClassA(sColor){ 2 this.color=sColor; 3 } 4 5 ClassA.prototype.sayColor=function(){ 6 alert(this.color); 7 }; 8 9 10 function ClassB(sColor,sName){ 11 ClassA.call(this.sColor); 12 thi.name=snName; 13 } 14 15 ClassB.prototype=new ClassA(); 16 ClassB.prototype.sayName=function() 17 { 18 alert(this.name); 19 }; 20 21 22 var objA=new ClassA("red"); 23 var objB=new ClassB("blue","Nicholas"); 24 objA.sayColor(); 25 objB.sayColor(); 26 objB.sayName();