一、类与对象
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。
调用一个对象的一个方法,以另一个对象替换当前对象。
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
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);
来源:https://www.cnblogs.com/sidmeng/archive/2011/10/09/2203694.html