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,
};