• JavaScript: __proto__和prototype


     图来源于:http://www.cnblogs.com/smoothLily/p/4745856.html

    个人的理解:

    1. 所有对象都有 __proto__属性,返回该对象的原型对象。例如f1由语句var f1 = new Foo()生成,那么f1.__proto__就是由构造函数Foo生成的原型对象Foo.prototype.

    f1.__proto__ === Foo.prototype; //true

    2. 所有函数具有prototype属性,这是一个指针,指向函数所生成对象的原型对象。Foo.prototype就是由 new Foo()函数所生成的这一类对象的原型,原型是可以被修改的:

    function Foo(){};
    var f1 = new Foo(); Foo.prototype.name = "emily"; f1.name; // "emily"

    如上代码所示,先生成对象f1,然后修改其对象原型,给它增加了一个name属性。f1因此也有了name属性。

    3. 但是函数也是一种对象,因此它也有__proto__属性,即也有其原型对象。对于函数(对象)Foo来说:

    Foo.__proto__ === Function.prototype; // true

    Function.prototype就是由new Function()所生成的这一类对象的原型。

    函数(对象)Foo的原型正是由Function函数所生成的原型。

    4. JavaScript的内置函数如Function, Object, Array, Date等,都既是构造函数,又是对象,因此他们都有prototype和__proto__属性。

    不同的是prototype指向的是其本身作为构造函数作用时所生成的对象的原型对象

    而__proto__属性是返回其本身作为对象的原型对象

    Function.__proto__ === Function.prototype; //true
    Array.__proto__ === Function.prototype; //true
    Date.__proto__ === Function.prototype; //true
    Object.__proto__ === Function.prototype; //true
    Foo.__proto__ === Function.prototype; //true

    5. 如上所示,所有(构造函数)对象的原型对象都是Function.prototype,这也是一个对象,在console中查看该对象,发现它返回的是一个空函数:

    Function.prototype.toString(); // 返回"function () {}"

    那么这个对象有没有原型对象呢,它的__proto__返回什么呢?

    Function.prototype.__proto__ === Object.prototype; // true

    所以

    Function.__proto__.__proto__ === Object.prototype; // true

    Array.__proto__.__proto__ === Object.prototype; // true
    Date.__proto__.__proto__ === Object.prototype; // true
    Object.__proto__.__proto__ === Object.prototype; // true
    Foo.__proto__.__proto__ === Object.prototype; // true

    6. Object.prototype也是一个对象,因此其__proto__属性返回:

    Object.prototype.__proto__; // null

    因此

    Function.__proto__.__proto__.__proto__; // null
    Array.__proto__.__proto__.__proto__; // null
    Date.__proto__.__proto__.__proto__; // null
    Object.__proto__.__proto__.__proto__; // null
    Foo.__proto__.__proto__.__proto__; // null
    f1.__proto__.__proto__.__proto__; // null

    任何对象向上回溯最终都会到null。

    7. 关于原型对象的constructor属性:每个函数对象都有名为“prototype”的属性,用于引用原型对象。此原型对象又有名为“constructor”的属性,它反过来引用函数本身。这是一种循环引用

    Foo.prototype.constructor === Foo; //true

    总结:理解这个概念的关键点就在于,__proto__是对象的属性,是用来向上查找其原型对象的。

    而prototype是函数的属性,其作用指向该构造函数所生成对象的原型。

    此外在stackoverflow上对这个问题的回答很有意思:

    __proto__ is the actual object that is used in the lookup chain to resolve methods, etc. 

    prototype is the object that is used to build __proto__ when you create an object with new:

    (new Foo).__proto__ === Foo.prototype; // 函数调用prototype属性用来构造对象原型
    
    (new Foo).prototype === undefined; // 对象没有prototype属性
     
  • 相关阅读:
    1. Ubuntu下使用pip方式安装tensorflow
    CSS 属性
    django运行django-admin.py无法创建网站
    jQuery各种效果举例
    一生莫轻舞,一舞一生苦
    即使你美丽动人,也要具备更华丽的着装
    即使有一颗强大的心,也要让人看到你美丽的外表
    python操作RabbiMQ
    windows下python安装paramiko
    python用paramiko将执行的结果存入excel表格
  • 原文地址:https://www.cnblogs.com/sufei-duoduo/p/5795300.html
Copyright © 2020-2023  润新知