3

I've read and tried understanding other answers similar to this question as well (like this one), But still the concept of prototypal inheritance is not very clear to me. and right now the thing that's confusing me the most is, that what is the actual difference between __proto__ and [[ Prototype ]]? As far as I've been able to understand is that [[ Prototype ]] is an "internal linkage that ties one object to another". But it gets ambiguous when I see a tutorial on youtube, because whenever they create an object and if they try to log it using console.log in their browser's console then it actually has the __proto__ property in it but when I try to do the same it outputs [[ Prototype ]] instead. So I'd like to know why is it so? and what is an "internal link"? Thanks in advance! :) Below's the code that outputs "[[ Prototype ]]" in chrome and "<prototype>" in firefox.

function User(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

const user = new User("Someone", "Something");

console.log(user);
ansme
  • 413
  • 2
  • 11
  • *"but when I try to do the same it outputs [[ Prototype ]] instead"*: please share the code that outputs that. – trincot Oct 09 '21 at 12:44
  • @trincot Hi I've added a snippet, kindly check it! – ansme Oct 09 '21 at 12:51
  • 1
    I think you are referring specifically to the way the *Chrome* console represents an object in the console. This is not related to JavaScript syntax, but implementation details of the console. – trincot Oct 09 '21 at 13:01
  • 1
    @trincot Yes that's what I meant! but after reading your answer it seems to me that they might have changed the way they represent it, because in almost every video that I've watched so far it always outputs `__proto__`. – ansme Oct 09 '21 at 13:09
  • thank you for articulating this @ansme, i was sure `[[prototype]]` was something new i was seeing in the console. i’ve tried googling things like `has __proto__ changed to [[prototype]] in chrome developer tools?` but google doesn’t understand what i am asking and doesn’t seem to return any relevant results. – user1063287 Nov 19 '21 at 13:45

2 Answers2

3

The double square bracket notation comes from the ECMAScript specification where it always refers to an internal entity (field, attribute, slot,...) but is not a notation you can use in JavaScript code. It is information for the implementer of the language and helps to precisely define the behaviour of the language.

In a console you may see information represented with these double brackets, as is the case in the Chrome console. Firefox uses a different notation: <prototype>.

Now to the core of your question. The link between an object and its prototype object is not an own JavaScript property of that object. It is an internal slot:

Internal slots correspond to internal state that is associated with objects and used by various ECMAScript specification algorithms. Internal slots are not object properties and they are not inherited.

You can get the prototype object via .__proto__, but that __proto__ property is a getter on the Object.prototype object. So that is like running in circles: when you write obj.__proto__, the engine needs to know what the prototype chain is before it can find that __proto__ value for you, since it needs to get it via inheritance -- it is not a property of obj itself. And to find the inheritance link the engine will use the internal "slot" [[Prototype]].

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Could you please elaborate a little more on what you mean by "internal slot"? And I also couldn't clearly understand when you mentioned "it's like running in circles when using __proto__"? – ansme Oct 09 '21 at 13:13
  • 1
    I expanded those paragraphs a bit. – trincot Oct 09 '21 at 13:17
  • In newbie language, is it close enough to say: `[[prototype]]` is a special type of property, present on all objects, whose value is a link to the object that it is a direct descendant of. Because you cannot call `[[prototype]]` directly, you use a special method, available on all objects, called `.__proto__` which returns the value of `[[prototype]]`, ie the object that it is a direct descendant of? And also note that the `.__proto__` method is deprecated in favour of [getPrototypeOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf)? – user1063287 Nov 19 '21 at 14:10
  • 1
    Yes, that sounds reasonable. Just realise that "special type of property" really means it is not a property in JavaScript terminology. It is implementation dependent how exactly the engine maintains this prototype link. It is actually good to stick with the wording of the specification and call this a "slot". Secondly, `__proto__` is a deprecated [*getter* and *setter*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#defining_getters_and_setters). – trincot Nov 19 '21 at 14:14
3

Each object's prototype is saved in the internal slot named as [[prototype]] and __proto__is just a getter/setter, defined in the Object.prototype object, to get the value of the [[prototype]] internal slot of any object.

Example:

const arr = [];

Each instance of an array gets Array.prototype as its prototype. So, in the above declaration of arr, [[prototype]] internal slot contains a reference to Array.prototype and in the following expression:

arr.__proto__ === Array.prototype  // true

arr.__proto__ gets the Array.prototype object from the internal [[prototype]] slot.

As mentioned above, __proto__ is just a getter/setter that gets the value of [[prototype]] internal slot and is only there for compatibility reasons. It shouldn't be used in modern javascript code; following two methods should be used to set/get the prototype of any object:


There are other internal slots, apart from [[prototype]], mentioned in the Ecmascript specification and these internal slots are not accessible by the javascript code we write.

If you need to know more about internal slots, read:

What is an "internal slot" of an object in JavaScript?

Yousaf
  • 27,861
  • 6
  • 44
  • 69
  • that makes things much clearer! But can you please elaborate a little on what an "internal slot" is? – ansme Oct 09 '21 at 13:16
  • I have included a link to another stackoverflow post in my answer that answers your question about "internal slots" in detail. – Yousaf Oct 09 '21 at 13:18