1,传统的方式:
原型链(过多的继承了太多的属性)
2,借用构造函数:
(用call或者apply用别人的工厂来实现自己的功能,不能继承别人构造函数的原型,每次构造函数都要多运行一个函数)
3,共享原型:
Father.prototype.lastName = "Deng";
function Father() {
}
function Son() {
}
Son.prototype = Father.prototype;
var father = new Father();
var son = new Son();
console.log(son.lastName );//Deng
-----------------------------------------------------------------
Father.prototype.lastName = "Deng";
function Father() {
}
function Son() {
}
function inherit(Targrt, Origin){
Targrt.prototype = Origin.prototype;
}
inherit(Son,Father);
var son = new Son()//
console.log(son.lastName );//Deng
但是这种共享原型的方式,Father和Son同时指向同一个原型,
那么如果我添加 Son.prototypr.sex = "male"
,那么father.sex = "male"
,
它们共用的一个原型,一个更改了原型上的属性,其他的都会更改。
4,圣杯模型:
Father.prototype.lastName = "Deng";
function Father() {}
function Son() {}
function inherit(Target, Origin){
function F() {} //新建一个空的构造函数
F.prototype = Origin.prototype;//让这个空的构造函数(F)的原型指向原始函数(Father)的原型
Target.prototype = new F();//让要继承函数(Son)的原型指向这个空函数的原型,这样这个要继承别人的函数添加自己原型属性,也不会污染那个原始函数。
}
inherit(Son,Father);
var son = new Son()
var father = new Father();
//这样就形成了Son继承子F,F继承自Father。
但是这个有一个问题,就是查看son的构造函数是Father(理应应该是Son),这里是有一个过程的:son.__proto__--->new F(),对象上没有constructor ,再往上找 new F().__proto__---->Father.prototype
,Father.prototype
上有constructor
,它指向Father
,这样就指向紊乱了。需要给它归位。如下:
function Father() {}
function Son() {}
function inherit(Target, Origin){
function F() {}
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target //让对象的constructor 属性指向自己。
Target.prototype.uber = Origin.prototype; //让对象的超类指向Origin的原型(可以写上方便以后查找超类)
}
inherit(Son,Father);
var son = new Son()
var father = new Father();
问题:如果把F.prototype = Origin.prototype;
和 Target.prototype = new F();
换个位置还能实现这种继承模式吗?
function inherit(Target, Origin){
function F() {}
Target.prototype = new F();
F.prototype = Origin.prototype;
}
这样就不行了,因为,new F()的是原来的那个原型,new完了再改让它指向Origin.prototype已经晚了。
5,关于圣杯模式的延伸:
function inherit(Target, Origin){
function F() {}
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target
Target.prototype.uber = Origin.prototype;
}
--------------------------------------------------------------------
var inherit = (function () {
var F = function () {};
return function (Target, Origin){
F.prototype = Origin.prototype;
Target.prototype = new F();
Target.prototype.constructor = Target
Target.prototype.uber = Origin.prototype;
}
}());
这两种方式下面的一种是闭包的封装,实现F函数的私有化(这一点可以去看闭包的作用的那一节),
因为F函数本来就是用来过渡的。(建议以后的圣杯模式就写成下面这种方式。)