1.通过原型链建立起对象之间的继承关系
还是上一篇文章的例子
Grand.prototype.lastName = "Deng";
function Grand(){}
var grand = new Grand();
Father.prototype = grand;
function Father(){
this.name = "xiaowang"
}
var father = new Father();
Son.prototype = father;
function Son(){
this.name = "xiaoLiu"
}
var son = new Son();
console.log(son.lastName);
通过原型链,son就可以访问father对象的属性和方向,也可以访问grand对象的属性和方法。
缺点:会继承到很多没用的属性。
2.call/aplay
function Person( name, age, sex ){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student ( name, age, sex, grade ){
Person.call(this,name,age,sex);
this.grade = grade;
}
var student = new Student( "wangWu", 18, "female", 2 )
像这样,通过已有的功能来创建自己的功能,也是一种继承模式。
缺点:只能借用构造函数,并不包含原型中的内容。实际上,调用Student函数并没有节省运行时间,因为在调用Student的时候实际上是执行了两个函数。
3.公有原型
Father.prototype.lastName = "Deng";
function Father(){}
function Son(){}
Son.prototype = Father.prototype
封装:
function inherit( target, origin ){
target.prototype = origin.prototype;
}
如果希望son的原型同时包含了father原型的属性就可以用这种方式。但是这种方法的缺点是更改son的原型,father的原型也会随之更改。
4.圣杯模式
方法跟公有原型相同,只是有一点改进
function inherit(target, origin){
function F(){}
F.prototype = origin.prototype;
target.prototype = new F();
}
这样改进之后,再修改target的原型就不会影响origin的原型。
但是还有一点需要注意,由于target的属性是继承自new F(),所以,constructor属性也被继承过来了,这样就会导致错乱,所以还应该再加一句。
function inherit(target, origin){
function F(){}
F.prototype = origin.prototype;
target.prototype = new F();
target.prototype.constructor = target;
target.prorotype.uber = origin.prototype; //真正继承自谁
}