js继承—圣杯模式

普通写法(会影响父类)

function Father(){

}

function Son(){

}

Father.prototype.lastName = "Deng";

//继承方式,公有原型
function inherit(Target,Origin){
    Target.prototype = Origin.prototype;
}
inherit(Son,Father);
var son = new Son;
console.log(son.lastName);

Son.prototype.sex = "male";//Father.prototype.sex 指向的是同一个,所以都会加上 male
//这里子类影响了父类

console.log(son.sex);
var father = new Father;
console.log(father.sex);//打印male

 

圣杯模式

增加中间层 F

function Father(){}
function Son(){}

Father.prototype.lastName = "Deng";

function inherit(Target,Origin){
    function F(){}
    F.prototype = Origin.prototype;
    Target.prototype = new F();
}
inherit(Son,Father);
var son = new Son;
var father = new Father;

console.log(son.lastName);//打印"Deng"
console.log(father.lastName);//打印"Deng"
Son.prototype.sex = "male";

console.log(son.sex);//打印male
console.log(father.sex);//undefined

 

这种中圣杯模式的本质在于,间生成了一个对象,起到了隔离的作用,今后为Son.prototype添加属性时,全部都会加在这个对象里面,所以不会对父级产生影响。而向上查找是沿着__proto__查找,可以顺利查找到父级的属性,实现继承。

下面来具体分析是如何进行继承的

  1. 首先inherit 函数中定义了一个function F ,F用来充当中间层的函数;
  2. 之后 F.prototype=Origin.prototype; 这一步表示,让F和Father的prototype指向同一地址,即Father.prototype;
  3. 下一步Target.prototype=new F(); 表示,通过函数F生成一个对象(这里把这个对象成为objF),让Son函数的prototype指向这个对象objF,到这一步实际上就已经实现了继承;
  4. 下方代码中,生成了son和father对象之后,对函数Son的prototype增加了一个sex属性,而Son函数的prototype是指向对象objF的,因此这个sex属性会加到objF之上,因此下方打印son.sex时就会出现male。
  5. 而对于son.lastName而言,首先查找Son函数内部是否有lastName属性,很明显没有。因此就沿着__proto__(即原型链)往上找, 即在函数F中找是否存在该属性,之前提到了F和Father的prototype都是指向Father.prototype的,而在Father.prototype中存在该属性,因此son.lastName的打印结果为Deng。
  6. 最后,由于有中间层F的存在,因此Father的prototype自始至终都没有受到影响,所以father.sex的打印结果为undefined。

 

Target.prototype.constructor=Target;
//由于Target.prototype指向的是objF,因此并没有constructor这一属性,沿着__proto__向上查找,
//发现constructor指向的是Father,因此这里可以进行归位,让它的constructor重新指向它自己

Target.prototype.uber=Origin.prototype;
//uber是超类的意思,这里主要用来储存这个目标到底继承自谁,可写可不写

 

利用闭包将F作为一个私有化变量

var inherit = (function(){
    var F = function(){};
    return function(Target,Orign){
        F.prototype = Orign.prototype;
        Target.prototype = new F();
        Target.prototype.constructor = Target;
        Target.prototype.uber = Orign.prototype;
    }
}());

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值