首页 > 解决方案 > Javascript 中令人困惑的 .constructor 属性

问题描述

下面的代码是我在浏览器中测试的。

function A(){}
a = new A()

a.__proto__ === a //false
a.__proto__.constructor === a.constructor //true

我很困惑为什么a.__proto__a分享相同.constructor

标签: javascript

解决方案


a.__proto__ === a是假的,因为a不是它自己的原型。它们是独立的对象

a.__proto__.constructor === a.constructor是真的,因为a对象继承constructor它的原型的属性。a因此,您可以(间接)或在其原型上访问该属性。

当你这样做时a = new A(),这里是你记忆中的一个粗略的想法(手挥手一些细节),这可能会有所帮助:

     +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− −−−−−−−−−−−−−−+
     | |
     | +−−−−−−−−−−−−−−−−+ |
A−−−−+−>| (函数) | |
        +−−−−−−−−−−−−−−−−+ |
        | 名称:“A” | +−−−−−−−−−−−−−−−−+ |
        | 原型 |−−−−−−−−−−−−−−−−−−−−−−−+−>| (对象) | |
        | [[原型]] |−>Function.prototype | +−−−−−−−−−−−−−−−−+ |
        | [[代码]] | | | 构造函数 |−+                
        +−−−−−−−−−−−−−−−−+ | | [[原型]] |−>Object.prototype
                                              | +−−−−−−−−−−−−−−−−−+
   +−−−−−−−−−−−−−−−−+ |  
a−>| (对象) | |
   +−−−−−−−−−−−−−−−−+ |
   | [[原型]] |−−−−−−−−−−−−−−−−−−−−−−−−−−−-+
   +−−−−−−−−−−−−−−−−−+           

[[Prototype]]是对象原型的链接,由 deprecated__proto__和 modern返回的值Object.getPrototypeOf()。另外:Function.prototype的原型是Object.prototype,上面没有显示。)

A是一个构造函数。它有一个属性 ,prototype它指向将用作通过 创建的对象的原型的对象new Aa是通过 创建的对象new A,因此它的原型 ( [[Prototype]]) 是同一个对象。该A.prototype对象有一个属性,constructor,它引用与其关联的构造函数(在简单的默认情况下)。

当您有两个实例时,它会变得更有用,a1并且a2. 让我们稍微修改一下代码:

// Part 1
function A(foo) {
    this.foo = foo;
}
A.prototype.method = function() {
    console.log(this.foo);
};

// Part 2
const a1 = new A("one");
const a2 = new A("two");

a1.method(); // "one"
a2.method(); // "two"

在上面的第 1 部分运行之后,我们有这样的东西(同样,省略了一些细节,我使用FpandOp而不是Function.prototypeandObject.prototype来节省空间):

     +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
     | |
     | +−−−−−−−−−−−−−−−−+ |
A−−−−+−>| (函数) | |
        +−−−−−−−−−−−−−−−−+ |
        | 名称:“A” | +−−−−−−−−−−−−−−−−+ |
        | 原型 |−−−−−>| (对象) | |
        | [[原型]] |−>Fp +−−−−−−−−−−−−−−−−+ |
        | [[代码]] | | 构造函数 |−+ +−−−−−−−−−−−−−−−−−+
        +−−−−−−−−−−−−−−−−+ | 方法 |−−−−−>| (函数) |
                               | [[原型]] |−>Op +−−−−−−−−−−−−−−−−−+
                               +−−−−−−−−−−−−−−−−+ | 名称:“方法” |
                                                      | [[原型]] |−>Fp
                                                      | [[代码]] |
                                                      +−−−−−−−−−−−−−−−−−−+

行后const a1 = new A("one");,我们有:

     +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−-−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
     | |
     | +−−−−−−−−−−−−−−−−+ |
A−−−−+−>| (函数) | |
        +−−−−−−−−−−−−−−−−+ |
        | 名称:“A” | +−−−−−−−−−−−−−−−−+ |
        | 原型 |−−−−−−+−>| (对象) | |
        | [[原型]] |−>Fp | +−−−−−−−−−−−−−−−−+ |
        | [[代码]] | | | 构造函数 |−+ +−−−−−−−−−−−−−−−−−+
        +−−−−−−−−−−−−−−−−+ | | 方法 |−−−−−>| (函数) |
                               | | [[原型]] |−>Op +−−−−−−−−−−−−−−−−−+
                               | +−−−−−−−−−−−−−−−−+ | 名称:“方法” |
                               | | [[原型]] |−>Fp
                               | | [[代码]] |
                               | +−−−−−−−−−−−−−−−−−−+
     +−−−−−−−−−−−−−−−−+ |
a1−−>| (对象) | |
     +−−−−−−−−−−−−−−−−+ |
     | 富:“一个”| |
     | [[原型]] |−−−−−−−−−−+
     +−−−−−−−−−−−−−−−−−+

行后const a2 = new A("two");,我们有:

     +−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−-−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
     | |
     | +−−−−−−−−−−−−−−−−+ |
A−−−−+−>| (函数) | |
        +−−−−−−−−−−−−−−−−+ |
        | 名称:“A” | +−−−−−−−−−−−−−−−−+ |
        | 原型 |−−−−−−+−>| (对象) | |
        | [[原型]] |−>Fp | +−−−−−−−−−−−−−−−−+ |
        | [[代码]] | | | 构造函数 |−+ +−−−−−−−−−−−−−−−−−+
        +−−−−−−−−−−−−−−−−+ | | 方法 |−−−−−>| (函数) |
                               | | [[原型]] |−>Op +−−−−−−−−−−−−−−−−−+
                               | +−−−−−−−−−−−−−−−−+ | 名称:“方法” |
                               | | [[原型]] |−>Fp
                               | | [[代码]] |
                               | +−−−−−−−−−−−−−−−−−−+
     +−−−−−−−−−−−−−−−−+ |
a1−−>| (对象) | |
     +−−−−−−−−−−−−−−−−+ |
     | 富:“一个”| |
     | [[原型]] |−−−−−−−−−−+
     +−−−−−−−−−−−−−−−−+ |
                               |
     +−−−−−−−−−−−−−−−−+ |
a2−−>| (对象) | |
     +−−−−−−−−−−−−−−−−+ |
     | 富:“两个”| |
     | [[原型]] |−−−−−−−−−−+
     +−−−−−−−−−−−−−−−−−+

这显示了原型如何用于共享功能。a1并且a2不需要拥有自己的副本method,他们只是从他们的原型中继承它。


旁注:__proto__已弃用。用于Object.getPrototypeOf(a)获取 的原型a,而不是a.__proto__.


推荐阅读