Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is __proto__ undefined?

While reading on Javascript's prototypes I encountered this behaviour I can't explain. I am testing this in chrome's console (which is V8).

var fruit = {taste:'good'};
var banana = Object.create(fruit);
console.log(banana.taste); //"good"
console.log(banana.__proto__); //Object {taste: "good"}
console.log(Object.getPrototypeOf(banana)); //Object {taste: "good"}

So far everything is as expected. However if I do this:

var drink = Object.create(null);
Object.defineProperty(drink, 'taste', {value:"nice"});
var coke = Object.create(drink);
console.log(coke.taste); //"nice"
console.log(coke.__proto__); //undefined
console.log(Object.getPrototypeOf(coke)); //Object {taste: "nice"}

then coke.__proto__ === undefined. Why is it undefined in the second case?

like image 431
Kaarel Purde Avatar asked Feb 17 '16 13:02

Kaarel Purde


People also ask

Why is prototype undefined?

Since the prototype is an object as well, if it does not contain the property either, its parent's prototype is checked. This process continues up the prototype chain until the property is found. If Object. prototype is reached and it does not have the property either, the property is considered undefined .

Is __ proto __ deprecated?

prototype. __proto__ Deprecated: This feature is no longer recommended.

What does __ proto __ mean in JavaScript?

__proto__ is a way to inherit properties from an object in JavaScript. __proto__ a property of Object. prototype is an accessor property that exposes the [[Prototype]] of the object through which it is accessed. POSTly is a web-based API tool that allows for fast testing of your APIs (REST, GraphQL).

What does __ proto __ in an object is pointing to?

__proto__ is an internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.


1 Answers

I once opened an issue for this behavior, but it was closed as standards-compliant behavior. According to the issue's close reason:

This is working as specified. ES6 __proto__ is a getter defined on Object.prototype. For an object that doesn't have that in its prototype chain it is not accessible (just like, say, hasOwnProperty isn't). You need to use Object.getPrototypeOf instead.

This is indeed true: ES6 section B.2.2.1 defines Object.prototype.__proto__; therefore, the __proto__ property is inherited from Object.prototype. However, your drink object was created with Object.create(null), so it doesn't have Object.prototype in its prototype chain.

An object always has internal knowledge to its prototype, stored in its [[Prototype]] internal slot. The __proto__ property is a way to access that internally-known prototype through code. An object's lack of a __proto__ property does not affect its [[Prototype]] slot, which still exists.

To be perfectly clear: coke does have a prototype (stored in [[Prototype]]), and that prototype is the object drink. You can see this with Object.getPrototypeOf(coke). However, that is the entire prototype chain, because the prototype of drink is null. Therefore, coke can't inherit __proto__ from Object.prototype.__proto__ because it doesn't have Object.prototype in its prototype chain.

like image 102
apsillers Avatar answered Nov 15 '22 14:11

apsillers