javascript之继承

流过昼夜 提交于 2020-03-27 09:41:03
一、类与对象
 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 SuperType11         SubType.prototype = new SuperType();12 13         SubType.prototype.getSubValue = function (){14             return this.subproperty;15         };16         var instance = new SubType();17         alert(instance.getSuperValue()); //true18 19         alert(instance instanceof Object); //true20         alert(instance instanceof SuperType); //true21         alert(instance instanceof SubType); //true22 23         alert(Object.prototype.isPrototypeOf(instance)); //true24         alert(SuperType.prototype.isPrototypeOf(instance)); //true25         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 black12 console.log(instance2.colors);//blue green13 console.log(instance1.name);zhangmeng14 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); 
 
 
 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!