2

Now I am learning JavaScript prototype and __proto__, and find several useful links

__proto__ VS. prototype in JavaScript

How does __proto__ differ from constructor.prototype?

I can get the value of __proto__ of object f in the following codes under Chrome.

var Foo = function() {}
var f = new Foo();
f.__proto__
> Foo {} 

However, after setting the Foo.prototype.__proto__ to null, the value of __proto__ is undefined.

var Foo = function() {}
Foo.prototype = {name: 'cat', age: 10};
Foo.prototype.__proto__ = null;
var f = new Foo();
f.__proto__
> undefined 

But I can get the value of f.name, which is cat. Here is my understanding, since the value f.name can be retrievable, the __proto__ of object f should point to Foo.prototype. Why the value of f.__proto__ is undefined?

Community
  • 1
  • 1
zangw
  • 43,869
  • 19
  • 177
  • 214
  • 1
    I think this is actually a *decent* question, even if the behavior (when investigated) happens to be browser-specific. *There is a very specific case/context asked about, which seems counter to face-value expectations*. `__proto__` has been long-supported in Chrome and Firefox (and WebKit?) and *is* standardized in ES6. Since this is *now semi-defacto behavior* (and upcoming supported behavior) and the *specific context is discussed* an "answer" of "should not use" is not really an answer, even if such a statement may make a good closing summary. – user2864740 Jul 01 '15 at 11:19
  • I've opened a bug for this behavior: https://code.google.com/p/chromium/issues/detail?id=506166 – apsillers Jul 01 '15 at 12:51
  • I answered this question incorrectly in July. I have corrected my answer. – apsillers Feb 17 '16 at 14:12
  • @apsillers, why the newest question could be duplicated as my question, IMO, my question is earlier than the duplicated one. please correct me, if I missing something – zangw Feb 17 '16 at 14:16

2 Answers2

5

__proto__ is an internal special property of JavaScript. you should not use.

From mdn

While Object.prototype.proto is supported today in most browsers, its existence and exact behavior has only been standardized in the ECMAScript 6 specification as a legacy feature to ensure compatibility for web browsers. For better support, it is recommended that only Object.getPrototypeOf() be used instead.

Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231
  • 2
    `__proto__` - at least the access of - is in ECMA 6th edition and *is* supported in Chrome in this manner, see [MDN's entry](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto). Anyway this "answer" does not address the question asked. Use a comment for a .. comment. – user2864740 Jul 01 '15 at 11:12
  • 3
    It does answer _"Why the value of `f.__proto__` is `undefined`?"_ – Cerbrus Jul 01 '15 at 11:13
  • `__proto__` is neither internal nor special. – Bergi Feb 17 '16 at 14:53
  • This answer does not answer the question; this answer is answering the question "Should I use `__proto__`?" which not being asked here. This might possibly be okay as a comment. If I ask on Biology.SE, "What is the chemical composition that makes nightshade plants so poisonous?" then it does not answer my question to tell me, "Nightshade plants are often lethally poisonous; you should not eat them." – apsillers Feb 17 '16 at 17:28
3

According to the ES2015 spec, __proto__ is an accessor property that is inherited from Object.prototype.

Since your prototype chain for the instance f is rooted in null, rather than Object.prototype, the f object does not inherit any properties from Object.prototype, including Object.prototype.__proto__.

The object still knows its prototype internally (through [[Prototype]] internal slot), but it does not inherit the __proto__ accessor property for getting this value. You can still access it through Object.getPrototypeOf(f), though.

See also the resolution on the Chromium issue "obj.__proto__ is undefined if prototype chain does not contain Object.prototype":

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.

apsillers
  • 112,806
  • 17
  • 235
  • 239