美文网首页JavaScript
[JavaScript] 原型继承的原理

[JavaScript] 原型继承的原理

作者: 何幻 | 来源:发表于2016-03-07 07:18 被阅读126次

    两条规则:

    1. 实例.__proto__ === 构造函数.prototype
    2. 实例.属性 === 如果自身有该属性 ? 实例.属性 : 实例.[__proto__]n次.属性

    关于规则2的解释:
    查找实例的属性时,先判断自身有没有这个属性,如果有,那么直接获取。
    否则,查找它的__proto__有没有这个属性,有的话,就是它,
    否则,查找它的__proto__.__proto__有没有这个属性……
    如果一直找不到,就是undefined。(此处必有蹊跷……略

    测试用例:(测试环境,Chrome 44,Win7)

    1. 考察构造函数和实例

    var F=function(){};    //构造函数F
    F.prototype={};    //先设置构造函数的prototype
    var f=new F;    //造一个实例
    console.assert(f.__proto__===F.prototype);    //根据规则1
    
    console.assert(f.a===undefined);    //实例还没有这个属性
    
    F.prototype.a=1;    //给prototype增加一个属性
    console.assert(f.a===f.__proto__.a);    //根据规则2
    console.assert(f.a===F.prototype.a);    //根据规则1
    console.assert(f.a===1);    //找到了属性值
    

    总结:

    f.a===f.__proto__.a
    ===F.prototype.a===1
    

    2. 考察继承

    var G=function(){};    //再来一个构造函数
    G.prototype=f;    //让这个构造函数的prototype是刚才那个实例
    var g=new G;    //再造一个实例
    console.assert(g.__proto__===G.prototype);    //根据规则1
    
    console.assert(g.__proto__===f);    //根据刚才的赋值
    console.assert(g.a===g.__proto__.a);    //根据规则2
    console.assert(g.a===f.a);    //根据上面的推导
    console.assert(g.a===1);    //找到了属性值
    

    总结:

    g.a===g.__proto__.a===g.__proto__.__proto__.a
    ===G.prototype.__proto__.a===f.__proto__.a===F.prototype.a===1
    

    3. 考察只读性

    g.a=2;    //为实例增加属于自己的属性
    console.assert(g.a===2);    //根据规则2
    console.assert(f.a===1);    //不影响其他实例的查找规则
    

    结论:
    原型继承,本质上利用了实例属性的查找规则。

    参考文献:
    《ECMAScript® 2015 Language Specification》——第3页 4.2.1

    相关文章

      网友评论

        本文标题:[JavaScript] 原型继承的原理

        本文链接:https://www.haomeiwen.com/subject/burnkttx.html