Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object.create setting __proto__ but not prototype

I'm pretty new to using object.create instead of the classical js way to acheive prototypical inheritance.

In Chrome at least I was surprised to see the following code:

var baseObject = {
test : function(){
    console.log('Child');
}
}

var newObject = Object.create(baseObject);
newObject.test = function(){
console.log('Parent');
this.__proto__.test();
}
console.log(newObject);

newObject.test();

Produces this (simulating the output in web tools):

Object {test: function, test: function} 
    test: function (){
    __proto__: Object
        test: function (){
        __proto__: Object
Parent
Child 

So you see it's not setting prototype but instead only "__proto__", which I thought was discouraged in its use. You can see that in my code I'm able to properly inherit, and call the parent object, but only using "__proto__". Using "prototype" results in an error (undefined).

What's going on here? I figured object.create would set the "prototype" instead as that is the standard (or so I had assumed). Why is it populating and making me using "__proto__"

like image 363
nahelm Avatar asked Mar 05 '13 21:03

nahelm


1 Answers

No using __proto__ to set up your prototypal inheritance is discouraged because it's non-standard. That doesn't mean you can't use Object.create() to make a new object with a particular prototype object.

Objects do not have a .prototype property by default. You're confusing the .prototype object of a function.

So if I have a function like this:

function Foo() {

}

That Foo function object has a .prototype property that references an object that will be used as the __proto__ of any objects created when invoked as a constructor.

var f = new Foo();

So now f is an object with the Foo.prototype in its prototype chain. You can verify this using Object.getPrototypeOf();

Object.getPrototypeOf(f) === Foo.prototype; // true

What Object.create gives you is the ability to set up the same prototype chain, but without using a constructor function. So this would be equivalent.

var f2 = Object.create(Foo.prototype);

Now we have an object that is set up in the same manner as the original f object.

Object.getPrototypeOf(f2) === Foo.prototype;            // true
Object.getPrototypeOf(f2) === Object.getPrototypeOf(f); // true

So it's just a different way of doing what is ultimately the same thing. The relationship between an object and its prototype chain is an internal relationship. The non-standard __proto__ just exposes that relationship.

like image 77
the system Avatar answered Sep 22 '22 01:09

the system