Reputation: 3813
Trying to understand Prototypes in Javascript. For this example:
var obj = new Function();
obj.prototype.x = "a";
Why do I get different results from
console.log(obj.__proto__);
and
console.log(obj.prototype);
Thanks
Upvotes: 2
Views: 160
Reputation: 26696
You're looking at this sideways...
.prototype
and .__proto__
are the same object (or are at one specific point in time)...
BUUUUUT they're propertes of different objects.
var Human = function (name) {
this.num_eyes = 2;
this.num_heads = 1;
this.name = name;
};
Human.prototype.die = function () { this.isAlive = false; };
var herman = new Human("Herman");
herman.__proto__.die === Human.prototype.die; // true
.__proto__
is a link to the CONSTRUCTOR .prototype (and typically, is the SAME object)
It's almost like this:
var Human = function () {
this = {};
this.num_eyes = 2;
// ......
this.__proto__ = Human.prototype;
};
That isn't exactly how constructors work, but really, that's the idea.
And that's why .__proto__
and .prototype
aren't the same thing.
Because you're looking in the wrong place.
So if:
var herman = new Human();
herman.__proto__ === Human.prototype;
var Human = new Function ();
...so logic then states that Human.__proto__ === Function.prototype;
...and if Human
and Function
aren't the same object, then their .prototype
properties aren't going to be the same (unless you overwrite one with the other Human.prototype = Function.prototype; Human.__proto__ === Human.prototype; //true
Upvotes: 0
Reputation: 147413
In:
> var obj = new Function();
a new function object is created whose internal [[Prototype]]
(or __proto__
in browsers that support it) references Function.prototype
, i.e. the built–in Function constructor's public prototype and assigned to the variable obj.
Because obj is a Function object, it has a prototype property by default just in case it is to be used as a constructor.
In:
> obj.prototype.x = "a";
a new x property is added to obj.prototype that is assigned a value of the string 'a'
. Note that obj only has a prototype property by default because it's a Function object.
So:
obj.prototype === obj.__proto__
is essentially:
obj.prototype === Function.prototype
which is clearly false.
So to answer the question "Best way to retrieve the prototype of a JS object" then you can access a constructor's public prototype through its prototype property.
You can access a instance's internal [[Prototype]]
using ES5 Object.getPrototypeOf, however it may not be supported everywhere.
You can also access a instance's internal [[Prototype]]
using the non–standard __proto__
where supported.
A more general solution is to keep a reference to the constructor's prototype at the time the instance is created (since changing the constructor's prototype at some later stage will not change the [[Prototype]]
of instances that have already been created).
So in a general case you might do:
function Foo() {
this.internalProto = Foo.prototype;
}
var foo = new Foo();
// ES5, where supported
Object.getPrototypeof(foo) == Foo.prototype; // true
foo.internalProto == Foo.prototype; // true
// Non–standard, Where supported
foo.internalProto == foo.__proto__; // true
Upvotes: 2
Reputation: 8053
According to this source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
Object.prototype.__proto__
points to the object which was used as prototype when the object was instantiated.
It simply means that object used as prototype to create Function object was empty function, and that's why you have function Empty() {}
in the output. You can observe it here:
console.log(Function.prototype);
var func = new Function();
console.log(func.__proto__);
console.log(func.prototype);
// OUTPUT:
// function Empty() {}
// function Empty() {}
// Object {}
__proto__
of an empty object (e.g. var a = {}
) is Object {}
because this is, what was used to create base of your object (in other words Object.prototype
was used). And prototype
is not even available as a property of a
, because you've created a totally empty object, so there's nothing.
Also notice that __proto__
is now deprecated.
Why? I don't know, but I have never used it so I don't care :)
prototype
is a different thing, e.g.
Changes to the
Object prototype object
are propagated to all objects unless the properties and methods subject to those changes are overridden further along the prototype chain.
This is why you need prototype
and you don't care about __proto__
in real life. If I'm wrong please show me useful usage of __proto__
.
Hope it's clearer now. And to answer your original question:
Prototype of a JS object can be retrieved only by using prototype
property, as __proto__
contains sth different. If prototype
property doesn't exist, there is no prototype of the JS object, even if sth was used in the process of instantiation.
Upvotes: 2
Reputation: 2645
Accordint to the MDN, obj.__proto__ has not been standardized.
So while obj.prototype has a clear standardized behav8our accross browsers, obj.__proto__ behaves differently in different browsers.
Upvotes: 0