美文网首页JavaScript 进阶营
javascript原型链图解

javascript原型链图解

作者: 黄老之学 | 来源:发表于2017-05-17 19:03 被阅读0次

    如果没搞懂原型,就不算真懂javascript。

    这篇文章是学习中对原型及原型链的理论的一个小总结,弄懂基本理论之后,在实践中加深对原型的认识和掌握。

    理解以下三点对理解原型有帮助:

    1. javascript中一切都是对象,函数本身也是对象。
    2. javascript中继承机制是通过原型实现的,这点不同于java等语言通过class实现。
    3. 从顶端看原型链有助于理解,原型链最顶端是null(一),下一层是{}(二),接下来就是各种原型分支(万物),一生二,二生三,三生万物

    函数对象及其 prototype 属性

    function Player(name) {
      this.name = name
    }
    

    定义函数A,函数A本身也是对象,函数对象中的prototype属性指向此函数所有实例的原型(__proto__)对象,这个原型对象中有一个constructor属性,constructor属性又指向函数A这个对象本身。以上面代码为例,示意图如下:

    函数对象及其prototype属性

    函数的所有实例中的__proto__属性都指向函数prototype属性所指向的对象

    const newPlayer = new Player('tom')
    //true
    console.log(newPlayer.__proto__ === Player.prototype)
    

    代码图解如下:


    原型链是用对象的__proto__属性链接起来的原型对象,函数的prototype属性和__proto__不是一回事,prototype指向的是函数所有实例的原型(__proto__),而函数的__proto__属性指向的是它自己的原型链上的原型对象。
    //false
    console.log(Player.__proto__ === Player.prototype);
    

    图示如下:


    函数的prototype和__proto__属性

    只有函数才有prototype属性,但是每个对象都有__proto__属性

    函数对象本身的原型链层次关系

    函数的原型链层次关系

    代码验证:

    //result: [Function] 即图中的Function prototype对象
    console.log(Player.__proto__);
    //result: {} 即图中的Object prototype对象
    console.log(Player.__proto__.__proto__);
    //result: null
    console.log(Player.__proto__.__proto__.__proto__);
    

    函数的原型(__proto__)与函数实例的原型(__proto__)不同

    验证代码如下:

    //[Function]函数的原型
    console.log(Player.__proto__);
    //Player {}函数实例的原型,与函数的prototype相同
    console.log(newPlayer.__proto__)
    //false
    console.log(Player.__proto__ === newPlayer.__proto__)
    

    每个对象都有constructor属性,constructor属性指向创建这个对象的函数,所以可以通过constructor属性调用它所指向函数的prototype属性

    验证代码如下:

    //创建两个Player函数的实例(对象)
    const player1 = new Player('tom')
    const player2 = new Player('tom')
    //[Function: Player]指向Player函数
    console.log(player1.constructor);
    //[Function: Player]指向Player函数
    console.log(player2.constructor);
    //true
    console.log(player1.constructor === player2.constructor);
    //[Function: Player]指向Player函数
    console.log(player1.__proto__.constructor);
    //[Function: Player]指向Player函数
    console.log(Player.prototype.constructor);
    //true
    console.log(player1.__proto__.constructor === Player.prototype.constructor);
    //函数实例的constructor属性与它的原型(__proto__)中的constructor属性相同,都指向函数对象
    console.log(player1.constructor === player1.__proto__.constructor);
    //Player {} 又指向了player2的(原型)`__proto__`对象
    console.log(player2.constructor.prototype);
    //true
    console.log(player1.constructor.prototype == player2.constructor.prototype);
    

    本文参考和使用了 從ES6開始的JavaScript學習生活 一书中的资源。

    相关文章

      网友评论

        本文标题:javascript原型链图解

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