对象不拥有什么 __proto__ 是显式设置的?
What don't objects own __proto__ which is explicity set?
我知道 __proto__
是在 Object.prototype
上定义的,所以普通对象不应该拥有它。
但为什么对象字面值不拥有 __proto__
,即使它已明确设置?
var obj = {
__proto__: 'hello',
normal_prop: 'world'
};
obj.hasOwnProperty('__proto__'); // false
obj.hasOwnProperty('normal_prop'); // true
也奇怪,
obj.__proto___ // {}
我认为这是因为 __proto__
被分配了一个非对象,但是:
var obj = {
__proto__: {value: 42},
};
obj.__proto__; // { value: 42 }
obj.hasOwnProperty('__proto__'); // false
obj.__proto__ = {value: 'hello world'}
obj.__proto__; // { value: 'hello world' }
obj.hasOwnProperty('__proto__'); // false
我看到有人将 __proto__
称为 "pseudo property",我想这可能是原因,但我找不到详细信息。我阅读了 ES6 规范中关于 __proto__
的部分,但没有太大帮助。
此行为存在于当前版本的 Firefox 和 Chrome。
我应该看哪里?
设置obj.__proto__
等同于使用Object.setPrototypeOf(obj, ...)
。
根据标准,setter 函数就是这样定义的。因此,当您分配 __proto__ 时,您实际上在做与调用 Object.setPrototypeOf
时相同的事情。您并没有真正为 __proto__ 属性 赋值,您是在为对象分配原型。
你可以很容易地看到它是这样的:
obj = {
__proto__: {value: 42}
};
Object.setPrototypeOf(obj, {value: 43});
console.log(obj.__proto__); // { value: 43 }
如果你想更深入,你可以在v8(Chrome javascript 引擎)源代码中查看详细信息,这里:
https://chromium.googlesource.com/v8/v8/+/refs/heads/4.2.76/src/v8natives.js
您会看到 __proto__ 的 setter 与 Object.setPrototypeOf 基本相同。
您甚至可以模仿以下行为:
obj = {
__proto__: {
value: 42
}
};
Object.defineProperty(obj, 'fakeProto', {
set: function(value) {
Object.setPrototypeOf(this, value)
}
})
obj.fakeProto = {
value: 43
};
console.log(obj.__proto__); // { value: 43 }
显然,最后一个示例与 __proto__ 的情况并不完全相同,它只是为了表明某些属性可以具有 setter 函数,而不仅仅是赋值。标准说 __proto__ 的 setter 需要做与 setPrototypeOf.
相同的事情
我知道 __proto__
是在 Object.prototype
上定义的,所以普通对象不应该拥有它。
但为什么对象字面值不拥有 __proto__
,即使它已明确设置?
var obj = {
__proto__: 'hello',
normal_prop: 'world'
};
obj.hasOwnProperty('__proto__'); // false
obj.hasOwnProperty('normal_prop'); // true
也奇怪,
obj.__proto___ // {}
我认为这是因为 __proto__
被分配了一个非对象,但是:
var obj = {
__proto__: {value: 42},
};
obj.__proto__; // { value: 42 }
obj.hasOwnProperty('__proto__'); // false
obj.__proto__ = {value: 'hello world'}
obj.__proto__; // { value: 'hello world' }
obj.hasOwnProperty('__proto__'); // false
我看到有人将 __proto__
称为 "pseudo property",我想这可能是原因,但我找不到详细信息。我阅读了 ES6 规范中关于 __proto__
的部分,但没有太大帮助。
此行为存在于当前版本的 Firefox 和 Chrome。
我应该看哪里?
设置obj.__proto__
等同于使用Object.setPrototypeOf(obj, ...)
。
根据标准,setter 函数就是这样定义的。因此,当您分配 __proto__ 时,您实际上在做与调用 Object.setPrototypeOf
时相同的事情。您并没有真正为 __proto__ 属性 赋值,您是在为对象分配原型。
你可以很容易地看到它是这样的:
obj = {
__proto__: {value: 42}
};
Object.setPrototypeOf(obj, {value: 43});
console.log(obj.__proto__); // { value: 43 }
如果你想更深入,你可以在v8(Chrome javascript 引擎)源代码中查看详细信息,这里: https://chromium.googlesource.com/v8/v8/+/refs/heads/4.2.76/src/v8natives.js
您会看到 __proto__ 的 setter 与 Object.setPrototypeOf 基本相同。
您甚至可以模仿以下行为:
obj = {
__proto__: {
value: 42
}
};
Object.defineProperty(obj, 'fakeProto', {
set: function(value) {
Object.setPrototypeOf(this, value)
}
})
obj.fakeProto = {
value: 43
};
console.log(obj.__proto__); // { value: 43 }
显然,最后一个示例与 __proto__ 的情况并不完全相同,它只是为了表明某些属性可以具有 setter 函数,而不仅仅是赋值。标准说 __proto__ 的 setter 需要做与 setPrototypeOf.
相同的事情