javascript - Javascript 中令人困惑的 .constructor 属性
问题描述
下面的代码是我在浏览器中测试的。
function A(){}
a = new A()
a.__proto__ === a //false
a.__proto__.constructor === a.constructor //true
我很困惑为什么a.__proto__
和a
分享相同.constructor
解决方案
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 A
。a
是通过 创建的对象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 部分运行之后,我们有这样的东西(同样,省略了一些细节,我使用Fp
andOp
而不是Function.prototype
andObject.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__
.
推荐阅读
- python - 您如何从肥皂响应中检索值
- drools - OptaPlanner 如何拒绝启发式部分的移动
- python-3.x - 有什么方法可以根据我绘制的二维数据更改 GLSL 中的背景颜色
- python - Pyinstaller 是否能够将 .py 文件与音频一起转换为 exe?
- opencv - 如果焦距和视差以像素为单位,视差图是否以米为单位提供深度?
- python - Matplotlib 由于空刻度而污染了 x 轴
- loops - 使用属性迭代中介表达式
- caching - Shopify 缓存 - 哪些操作会导致清除缓存
- javascript - 使用没有访问令牌的 MapBox GL JS
- sql - 在存储过程中多次更新表时如何避免死锁?