Reputation: 263
I understand that __proto__
is defined on Object.prototype
so normal objects shouldn't own it.
But why don't object literals own __proto__
even if it is explicitly set?
var obj = {
__proto__: 'hello',
normal_prop: 'world'
};
obj.hasOwnProperty('__proto__'); // false
obj.hasOwnProperty('normal_prop'); // true
Also strangely,
obj.__proto___ // {}
I thought this was due to __proto__
being assigned a non-object, but:
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
I see people referring to __proto__
as a "pseudo property", and I guess this might be the reason, but I can't find details. I read the section on __proto__
in the ES6 spec but it didn't help much.
This behavior is present in the current version of Firefox and Chrome.
Where should I be looking at?
Upvotes: 0
Views: 56
Reputation: 17124
Setting obj.__proto__
is the equivalent of using Object.setPrototypeOf(obj, ...)
.
The setter function is defined that way, according to the standard. So when you assign __proto__, you're in fact doing the same thing as when you call Object.setPrototypeOf
. You're not really giving a value to a __proto__ property, you're assigning a prototype to your object.
You can see it easily like this:
obj = {
__proto__: {value: 42}
};
Object.setPrototypeOf(obj, {value: 43});
console.log(obj.__proto__); // { value: 43 }
If you want to go deeper, you can see details in v8 (Chrome javascript engine) source code, here: https://chromium.googlesource.com/v8/v8/+/refs/heads/4.2.76/src/v8natives.js
You'll see that the setter for __proto__ is basically the same thing as Object.setPrototypeOf.
You can even mimic the behavior:
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 }
Obviously the last example is not exactly what happens with __proto__, it's just to show that some properties can have setter functions that don't simply assign a value. And the standard says that the setter for __proto__ needs to do the same thing as setPrototypeOf.
Upvotes: 1