简体   繁体   English

为什么Object.prototype的__proto__,另一个Object.prototype?

[英]Why is the __proto__ of Object.prototype, another Object.prototype?

If we create an array in chrome console,如果我们在 chrome 控制台中创建一个数组,

arr=[1,2];

and check the prototype chain in chrome devtools using arr.__proto__.__proto__ , we get the following result.并使用arr.__proto__.__proto__检查 chrome devtools 中的原型链,我们得到以下结果。 在此处输入图像描述

As you can see, the __proto__ object is pointing to null, which I was expecting logically.如您所见,__ __proto__ object 指向 null,这符合我的逻辑预期。 But when I tried to access the same level of the prototype chain, ie the Object.Prototype , by using arr.__proto__ , and then searching through the dropdown menus, I got the following result.但是当我尝试使用arr.__proto__访问原型链的同一级别时,即Object.Prototype ,然后搜索下拉菜单,我得到了以下结果。 在此处输入图像描述

As you can see in the highlighted line, this time the __proto__ is pointing to another Object.Prototype .正如您在突出显示的行中看到的,这次__proto__指向另一个Object.Prototype On opening this further, I got the same contents as I got in the previous command(check previous pic).进一步打开它时,我得到了与上一个命令中相同的内容(查看上一张图片)。

Can someone please tell me how this extra layer of an Object.prototype is created in some commands, but not in others?有人能告诉我Object.prototype的这个额外层是如何在某些命令中创建的,而在其他命令中却没有吗?

PS I'm just learning prototypal inheritance, and this was my attempt to understand how it is implemented in the JS environment. PS 我只是在学习原型 inheritance,这是我试图了解它是如何在 JS 环境中实现的。

This is due to an odd behavior in Chrome dev tools.这是由于 Chrome 开发工具中的一个奇怪行为。 The (now deprecated) __proto__ property is a getter/accessor property, which means when it is accessed, it runs a portion of code. (现已弃用) __proto__属性是一个 getter/accessor 属性,这意味着当它被访问时,它会运行一部分代码。 That portion of code looks something like so:那部分代码看起来像这样:

Object.getPrototypeOf(this); // which returns this[[Prototype]]

The this in the above example is typically the object that you call .__proto__ on.上面示例中的this通常是您调用.__proto__的 object。 For example, if you did arr.__proto__ , then this would be arr , so we end up getting the prototype of the arr array as expected.例如,如果你做了arr.__proto__ ,那么this就是arr ,所以我们最终得到了预期的arr数组的原型。 In the Chrome dev tools console, things are a little different.在 Chrome 开发工具控制台中,情况有些不同。 Rather than the getter being invoked on an object like arr , it is instead invoked manually when you press (...) : getter 不是像arr那样在 object 上调用,而是在您按下(...)时手动调用:

显示如何为 proto getter 属性按下省略号图标的图像

So now the question is - what is the value of this when performing Object.getPrototypeOf(this);所以现在的问题是 - 执行Object.getPrototypeOf(this); this this 的值是多少; inside of the __proto__ getter when it is invoked manually in the Chrome dev tools rather than invoking it via property access such as arr.__proto__ ?__proto__ getter 内部,当它在 Chrome 开发工具中手动调用时,而不是通过诸如arr.__proto__之类的属性访问来调用它? This is up to the Chrome dev tools team to decide, but it seems like the way that it behaves is that it sets the this to the originally logged object 1 .这由 Chrome 开发工具团队决定,但它的行为方式似乎是将this设置为最初记录的 object 1 In your second example, that object is arr.__proto__ .在您的第二个示例中, object 是arr.__proto__ As a result, the getter ends up showing the prototype of arr.__proto__ again, rather than null .结果,吸气剂最终再次显示arr.__proto__的原型,而不是null

The below code snippet (see Chrome console output), is a simple example of this behavior in action:下面的代码片段(请参阅 Chrome 控制台输出)是此行为的一个简单示例:

 const obj = Object.create({ get nested() { console.log("obj === this:", this === obj); // true console.log("obj[[Prototype]] === this:", this === Object.getPrototypeOf(obj)); // false return this; } }, { foo: { value: 'bar', enumerable: true } }); // View chrome console for output console.log(obj);

In the above example, a new object is created with the property {foo: "bar"} which has a prototype set to an object with a getter called nested() {} .在上面的示例中,创建了一个新的 object,其属性为{foo: "bar"} ,其原型设置为 object,其吸气剂名为nested() {} This getter returns and logs the value of this .此 getter 返回并记录this的值。 When the above code is run in Chrome, and the getter is invoked by clicking (...) on obj[[Prototype]] (ie: obj.__proto__ ) nested property, you get the following output:当上面的代码在 Chrome 中运行时,通过在obj[[Prototype]] (即: obj.__proto__nested属性上单击(...)调用 getter,您将获得以下 output:

图像显示嵌套的 getter 记录了原始对象

In the above, the two red boxes represent the same object, showing that this inside of the getter doesn't refer to the prototype object (ie: {nested: (...)} ) when it is invoked using (...) , but rather it refers to the originally logged object. Unlike this, when you use arr.__proto__.__proto__ , the object logged is Object.prototype , so when you invoked the __proto__ getter, the this refers to the object Object.prototype , which returns null when its prototype is accessed.上图中,两个红色框代表相同{nested: (...)} ,表明 getter 内部的this在使用(...) ,而是指最初记录的 object。与此不同,当您使用arr.__proto__.__proto__时,记录的 object 是Object.prototype ,因此当您调用__proto__ getter 时, this指的是 object Object.prototype访问其原型时返回null

To properly walk the prototype chain, you can use nested calls to Object.getPrototypeOf() :要正确遍历原型链,您可以使用对Object.getPrototypeOf()的嵌套调用:

Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(arr))); // null

1 This is just an assumption based on some observations, but might not be correct - I'm not entirely sure how chrome decides what to set the this to, but the important thing to note is that it isn't always the immediate object that the getter property appears in. 1这只是基于一些观察的假设,但可能不正确 - 我不完全确定 chrome 如何决定将this设置为什么,但需要注意的重要一点是,它并不总是立即的 object吸气剂属性出现在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM