Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is foo.hasOwnProperty('__proto__') equal to false?

var foo = {
  bar : 5
}

Why is foo.hasOwnProperty('__proto__') equal to false?

It can't be from any object in the prototype chain higher up, because it is specific to this very object.

EDIT:

Some answers say that it is on Object.prototype.

But I don't understand how that makes sense. My question is not where it is, but why it isn't where it should be.

For example:

var a = new Foo();
var b = new Bar();
// Foo inherits from Bar

So shouldn't a.__proto__ be equal to b.__proto__?

Since they're both reading off Object.prototype ?

like image 423
batman Avatar asked Jun 18 '14 22:06

batman


1 Answers

In fact, __proto__ is inherited from Object.prototype:

foo.hasOwnProperty('__proto__')              // false
Object.prototype.hasOwnProperty('__proto__') // true

And according to MDN article,

There is nothing special about the __proto__ property. It is simply an accessor property -- a property consisting of a getter function and a setter function -- on Object.prototype.

As you say, intuitively it can seem that, since __proto__ is intrinsically related to each object, it should be an own property.

But it isn't like this. Instead, Object.prototype.__proto__ has a getter function which returns differently when called on different objects.

You can obtain something similar if you run

Object.defineProperty(
    Object.prototype,
    'self',
    {get: function(){return this}}
)

Now you can call .self on different objects and you will get different results.

Also note this behavior isn't exclusive of __proto__. For example, the id property of an HTML element isn't an own property neither:

var el = document.createElement('div');
el.id = 'foo';
el.hasOwnProperty('id');                // false
Element.prototype.hasOwnProperty('id'); // true

(Webkit browsers don't follow the spec and el.hasOwnProperty('id') is true)

like image 79
Oriol Avatar answered Oct 01 '22 12:10

Oriol