Reputation: 1056
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__"
Upvotes: 5
Views: 1320
Reputation: 39192
Object.create()
sets the prototype for that particular object instance. prototype
is a property on a constructor function that is the object automatically assigned as the [[Prototype]] for each instance created by using the new
operator with that constructor function.
__proto__
is a non-standard way to access the [[Prototype]] for a particular instance. You can also call Object.getPrototypeOf(this) for a standard way to access the prototype.
Upvotes: 0
Reputation: 9336
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.
Upvotes: 5
Reputation: 359836
An instance's __proto__
property should be the same as the constructor's prototype
property.
When an object is created, its
__proto__
property is set to reference the same object as its internal[[Prototype]]
(i.e. its constructor'sprototype
object). Assigning a new value to__proto__
also changes the value of the internal[[Prototype]]
property, except where the object is non–extensible.
Upvotes: 0