js继承模式

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.prototypeFather.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函数本来就是用来过渡的。(建议以后的圣杯模式就写成下面这种方式。)

猜你喜欢

转载自blog.csdn.net/weixin_43623871/article/details/88604368