A property definition of the form __proto__: value
or "__proto__": value
does not create a property with the name __proto__
. Instead, if the provided value is an object or null
, it points the [[Prototype]]
of the created object to that value. (If the value is not an object or null
, the object is not changed.)
Note that the __proto__
key is standardized syntax, in contrast to the non-standard and non-performant Object.prototype.__proto__
accessors. It sets the [[Prototype]]
during object creation, similar to Object.create
— instead of mutating the prototype chain.
const obj1 = {};
console.log(Object.getPrototypeOf(obj1) === Object.prototype);
const obj2 = { __proto__: null };
console.log(Object.getPrototypeOf(obj2));
const protoObj = {};
const obj3 = { "__proto__": protoObj };
console.log(Object.getPrototypeOf(obj3) === protoObj);
const obj4 = { __proto__: "not an object or null" };
console.log(Object.getPrototypeOf(obj4) === Object.prototype);
console.log(Object.hasOwn(obj4, "__proto__"));
Only a single prototype setter is permitted in an object literal. Multiple prototype setters are a syntax error.
Property definitions that do not use "colon" notation are not prototype setters. They are property definitions that behave identically to similar definitions using any other name.
const __proto__ = "variable";
const obj1 = { __proto__ };
console.log(Object.getPrototypeOf(obj1) === Object.prototype);
console.log(Object.hasOwn(obj1, "__proto__"));
console.log(obj1.__proto__);
const obj2 = { __proto__() { return "hello"; } };
console.log(obj2.__proto__());
const obj3 = { ["__proto__"]: 17 };
console.log(obj3.__proto__);
const obj4 = { ["__proto__"]: 17, __proto__: {} };
const obj5 = {
["__proto__"]: 17,
__proto__: {},
__proto__: null,
};
const obj6 = {
["__proto__"]: 17,
["__proto__"]: "hello",
__proto__: null,
};
const obj7 = {
["__proto__"]: 17,
__proto__,
__proto__: null,
};