What is the significance of the double brackets for the [[prototype]] property in JavaScript?
I know that every JavaScript object has an internal property called [[Prototype]]
. Some implementations allow access to it via a property called __proto__
while other do not. Is there any special significance of the brackets surrounding this property?
It is an "internal property" of the object. From ECMAScript 8.6.2:
This specification uses various internal properties to define the semantics of object values. These internal properties are not part of the ECMAScript language. They are defined by this specification purely for expository purposes. An implementation of ECMAScript must behave as if it produced and operated upon internal properties in the manner described here. The names of internal properties are enclosed in double square brackets [[ ]].
The statement, "These internal properties are not part of the ECMAScript language," means that internal properties are not identifiers that can be used in actual code -- internal properties are not accessible as members of the objects that contain them. However, they may be made accessible by particular functions or properties (e.g., some browsers are kind enough let you set and get [[Prototype]]
through the __proto__
property, and the ES5 spec allows read-only access through Object.getPrototypeOf
).
The use of double brackets over single brackets is probably to avoid any possible confusion with actual bracket notation (i.e., property access).
JavaScript [[Prototype]]
The double bracket [[Prototype]]
is an internal linkage that ties one object to another.
When creating a function, a property object called prototype is being created and added to the function's name variable (that we call constructor
). This object points to, or has an internal-private link to, the native JavaScript Object).
Example:
function Foo () {
this.name = 'John Doe';
}
// Foo has an object 'property' called prototype
// prototype was created automatically when we declared the function Foo.
// Now, we can assign properties to it without declaring the prototype object first.
Foo.prototype.myName = function () {
return 'My name is ' + this.name;
}
Now, if we'll create a new object out of Foo
using the new
keyword, we basically creating (among other things) a new object that has an internal link to the function's prototype (Foo
) we discussed earlier:
var obj = new Foo();
obj.__proto__ === Foo.prototype // true
obj.[[Prototype]] === Foo.prototype // true
as
obj.__proto__ === obj.[[Prototype]] // true
Since [[Prototype]]
is a private linkage to that function's object, many browsers are providing us with a public linkage instead. That is the __proto__
(pronounced as dunder proto).
__proto__
is actually a getter function that belong to the native JavaScript Object and returns the internal-private prototype linkage of whatever the this
binding is (returns the [[Prototype]]
of obj
):
obj.__proto__ === Foo.prototype // true
BTW, starting from ES5
, we can use the getPrototypeOf
method to get the internal private linkage:
obj.__proto__ === Object.getPrototypeOf(obj) // true
NOTE: this answer doesn't intend to cover the whole process of creating new objects or new constructors, but to help better understand what is the [[Prototype]]
and how it works.
The reason it's in brackets is to denote that it's a private property. The brackets themselves are never used in code anywhere.
As you pointed out, some implementation provide access to that private property under __proto__
, but it's non-standard.