javascript之继承

一、类与对象
 1、对象与类
1  var a={};//对象,无法用new实例化
2 function Person(name){
3 this.name=name;
4 }
5 Person.prototype.showName=function(){
6 alert(this.name);
7 }
8 var p=new Person("zhangmeng");
9 p.showName();

组合使用构造函数模式和原型模式实现的类:
构造函数定义属性;原型实现定义方法和属性共享
 1 function Person(name,age,job){
2 this.name=name;
3 this.age=age;
4 this.job=job;
5 this.friends=["y"]//共享属性
6 }//构造函数定义实例属性
7 Person.prototype={
8 constructor:Person,
9 sayName:function(){
10 alert(this.name);
11 }//原型模型用于定义方法和共享属性
12 }
13 var p1=new Person("zhangmeng",24,"Coding");
14 var p2=new Person("jiangyu",26,"Fighting");
15 p1.friends.push("dy");
16 console.log(p1.friends);
17 console.log(p2.friends);
18 p1.sayName();
19 p2.sayName();
 
2、constructor和prototype
constructor是对象的属性(Object)
prototype是函数的属性(Object),构造函数的prototype指向原型对象,它含有constructor指向构造函数。
 
3、instanceof和constructor判断对象类型
var d=new Date();
d.constructor==Date;//true
d instanceof Date //true
区别:d instanceof Object;//true
d.constructor==Object;//false
contructor不识别继承的类型
 
二、继承
1、理解构造函数、原型对象、实例的关系
构造函数中含有原型对象,原型对象包含指向构造函数的指针(constructor);实例中包含内部属性_proto_指向原型对象。
 
2、原型链继承
 1    function SuperType(){
2 this.property = true;
3 }
4 SuperType.prototype.getSuperValue = function(){
5 return this.property;
6 };//父类
7 function SubType(){
8 this.subproperty = false;
9 }//子类
10 //inherit from SuperType
11 SubType.prototype = new SuperType();
12
13 SubType.prototype.getSubValue = function (){
14 return this.subproperty;
15 };
16 var instance = new SubType();
17 alert(instance.getSuperValue()); //true
18
19 alert(instance instanceof Object); //true
20 alert(instance instanceof SuperType); //true
21 alert(instance instanceof SubType); //true
22
23 alert(Object.prototype.isPrototypeOf(instance)); //true
24 alert(SuperType.prototype.isPrototypeOf(instance)); //true
25 alert(SubType.prototype.isPrototypeOf(instance)); //true

     子类通过修改prototype属性,继承父类,实现原型链,而实现继承。当子类实例调用父类方法时候,搜索的步骤是:

1)实例化对象。2)子类方法。3)父类方法。4)Object,所有对象的祖先。
    缺点:包含引用类型的原型,包含引用类型的原型属性会被所有实例共享;不能向超类构造函数传递参数。
 
3、call和apply方法
 call和apply都是Function对象的方法,可用来改变对象的内部指针。JS说明如下:
call 方法
调用一个对象的一个方法,以另一个对象替换当前对象。
call([thisObj[,arg1[, arg2[,   [,.argN]]]]])
参数:thisObj可选项。将被用作当前对象的对象。arg1, arg2,  , argN可选项。将被传递方法参数序列。
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。
apply传入第二个参数是数组形式,如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])
var func=new function(){this.a="func"}
    
var myfunc=function(x){
        
var a="myfunc";
        alert(
this.a);
        alert(x);
    }
    myfunc.call(func,
"var");// 弹出func和var
 
4、借用构造函数(Constructor Stealing)实现继承
 
 1 function SuperType(name){
2 this.name=name;
3 this.colors=["blue","green"];
4 }
5 function SubType(){
6 SuperType.call(this,"zhangmeng");//利用call在SubType的环境下调用SuperType的方法
7 }
8 var instance1=new SubType();
9 instance1.colors.push("black");
10 var instance2=new SubType("jiangyu");
11 console.log(instance1.colors);//blue green black
12 console.log(instance2.colors);//blue green
13 console.log(instance1.name);zhangmeng
14 console.log(instance2.name);jiangyu

缺点:无法实现复用。
 
5、组合继承(Conbination inheritance)***
 构造函数实现对实例属性的继承;原型链实现方法和原型(共享)属性的继承:
 1 function SuperType(name){
2 this.name=name;
3 this.friends=["y"];
4 }
5 SuperType.prototype={
6 constructor:SuperType,
7 sayName:function(){
8 alert(this.name);
9 }
10 }
11
12 function SubType(name,age){
13 SuperType.call(this,name);//构造函数实现对实例属性的继承
14 this.age=age;
15 }
16 SubType.prototype=new SuperType();//原型链实现对原型属性和方法的继承
17
18 SubType.prototype.sayAge=function(){
19 alert(this.age);
20 }
21 var sub1=new SubType("zhangmeng",24);
22 sub1.sayName();
23 sub1.sayAge();
24 sub1.friends.push("dy");
25 console.log(sub1.friends);
26
27 var sub2=new SubType("jiangyu",26);
28 sub2.sayName();
29 sub2.sayAge();
30 sub2.friends.push("xp");
31 console.log(sub2.friends);
32


缺点:两次调用超类构造函数
 
6 寄生组合式继承(YUI:YAHOO.long.extend)
 
由于重写类型:SuperType.call(this,name),失去默认的constructor因此重新创建即可代替
SubType.prototype=new SuperType(),
减少一次调用,实现代码:
 1  
2 function inheritPrototype(subType,superType){
3 var prototype=object(superType.prototype);//创建超类原型对象副本
4 prototype.constructor=subType;//弥补由于call方法失去的默认constructor属性
5 subType.prototype=prototype;//子类的prototype指向超类的原型对象
6 }
7
8 function SuperType(name){
9 this.name=name;
10 this.friends=["y"];
11 }
12 SuperType.prototype={
13 constructor:SuperType,
14 sayName:function(){
15 alert(this.name);
16 }
17 }
18
19 function SubType(name,age){
20 SuperType.call(this,name);//构造函数实现对实例属性的继承
21 this.age=age;
22 }
23 //改写为:
24 inheritPrototype(SubType,SuperType);
25 SubType.prototype.sayAge=function(){
26 alert(this.age);
27 }
28 var sub1=new SubType("zhangmeng",24);
29 sub1.sayName();
30 sub1.sayAge();
31 sub1.friends.push("dy");
32 console.log(sub1.friends);
33
34 var sub2=new SubType("jiangyu",26);
35 sub2.sayName();
36 sub2.sayAge();
37 sub2.friends.push("xp");
38 console.log(sub2.friends);
 
 
 

posted on 2011-10-09 14:52  萌@宇  阅读(225)  评论(0编辑  收藏  举报

导航