Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct description of __proto__ initializer and distinct it from the accessors #16091

Merged
merged 4 commits into from
May 17, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The `__proto__` property of {{JSxRef("Object.prototype")}} is an accessor proper

The use of `__proto__` is controversial and discouraged. It was never originally included in the ECMAScript language spec, but modern browsers implemented it anyway. Only recently was the `__proto__` property standardized by the ECMAScript 2015 specification for compatibility with web browsers, so it will be supported into the future. It is deprecated in favor of {{JSxRef("Object.getPrototypeOf")}}/{{JSxRef("Reflect.getPrototypeOf")}} and {{JSxRef("Object.setPrototypeOf")}}/{{JSxRef("Reflect.setPrototypeOf")}} (though still, setting the `[[Prototype]]` of an object is a slow operation that should be avoided if performance is a concern).

The `__proto__` property can also be used in an object literal definition to set the object `[[Prototype]]` on creation, as an alternative to {{JSxRef("Object.create()")}}. See: [object initializer / literal syntax](/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer).
The `__proto__` property can also be used in an object literal definition to set the object `[[Prototype]]` on creation, as an alternative to {{JSxRef("Object.create()")}}. See: [object initializer / literal syntax](/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer). This syntax is **standard and optimized**, and is not the same concept as `Object.prototype.__proto__`.
sideshowbarker marked this conversation as resolved.
Show resolved Hide resolved

## Description

Expand Down Expand Up @@ -91,13 +91,9 @@ fn.prototype.myname = function () {
console.log('myname');
};

var obj = {
__proto__: fn.prototype
};

var obj = {};
obj.__proto__ = fn.prototype;
obj.myname(); // myname


```

## Specifications
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ let mergedObj = { ...obj1, ...obj2 }

> **Warning:** Note that {{jsxref("Object.assign()")}} triggers [setters](/en-US/docs/Web/JavaScript/Reference/Functions/set), whereas the spread operator doesn't!

### Prototype mutation
### Prototype setter

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`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/null), it changes the `[[Prototype]]` of the created object to that value. (If the value is not an object or `null`, the object is not changed.)
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`](/en-US/docs/Web/JavaScript/Reference/Global_Objects/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.)

```js
let obj1 = {}
Expand All @@ -279,9 +279,9 @@ assert(Object.getPrototypeOf(obj4) === Object.prototype)
assert(!obj4.hasOwnProperty('__proto__'))
```

Only a single prototype mutation is permitted in an object literal. Multiple prototype mutations are a syntax error.
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 mutations. They are property definitions that behave identically to similar definitions using any other name.
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.

```js
let __proto__ = 'variable'
Expand All @@ -298,6 +298,8 @@ let obj3 = {['__prot' + 'o__']: 17}
assert(obj3.__proto__ === 17)
```

Note that the `__proto__` key is standardized syntax, in contrast to the non-standard and non-performant {{jsxref("Object/proto", "Object.prototype.__proto__")}} accessors. It sets the `[[Prototype]]` during object creation, similar to {{jsxref("Object.create")}} — instead of mutating the prototype chain.

## Specifications

{{Specifications}}
Expand Down