Reputation: 451
I am trying to figure out the prototype chain of a function that I wrote
function Animal(voice)
{
this.voice = voice|| 'meaw'
}
Animal.prototype.speak =function() {
console.log(this.voice);
}
I know that the Animal function has a prototype property which point to it's prototype object. It's prototype object has constructor which points back and __proto__ property which points to Object object prototype
I am aware that every function object inherits from Function's object prototype and which inherit from Object's object prototype including __proto__ property. Now when I further investigated it, I found out that Function's object prototype and __proto__ property links to the same prototype object.
console.log(Animal.__proto__.constructor.__proto__ == Animal.__proto__.constructor.prototype ); //true
console.log(Animal.__proto__.constructor.__proto__ == Animal.__proto__); //true
Then I did some further test to prove it
Animal.__proto__.constructor.__proto__.test = 28;
console.log(Animal.__proto__.constructor.__proto__.test); // prints 28
console.log(Animal.__proto__.test); //prints 28
That means it's prototype and the prototype from it is inheriting are same. Any reason why it is set like that?
Upvotes: 2
Views: 908
Reputation: 27204
Animal
is a function and like all functions (unless you modify it), it links back to the Function.prototype
object. So:
Animal.__proto__ === Function.prototype //true
Now if we replace Animal.__proto__
with Function.prototype
, we get:
Function.prototype.constructor.__proto__ === Function.prototype
Why is that? Function.prototype.constructor
links back to its constructor, which is the Function
constructor. So this actually means:
Function.__proto__ === Function.prototype
If you're wondering why both Function.__proto__
and Function.prototype
share the same value, have a look at the specification.
The Function constructor is itself a built-in function object. The value of the [[Prototype]] internal slot of the Function constructor is %FunctionPrototype%, the intrinsic Function prototype object (19.2.3).
The Function.prototype
property shares the same value:
The value of Function.prototype is %FunctionPrototype%, the intrinsic Function prototype object (19.2.3).
So, since both Function
and the result of new Function()
are functions, they share the same [[Prototype]]
:
var func = new Function()
Function.__proto__ === func.__proto__
Upvotes: 1
Reputation: 5316
I found out that Function's object prototype and proto property links to the same prototype object.
You are mixing "prototype property" and "prototype object".
.prototype
is a property on constructor function. Whenever constructor is called, it creates object with prototype object set to Constructor.prototype
.
function Animal(){}
let animal = new Animal();
animal.__proto__ = Animal.prototype;
In fact, __proto__
property is just getter defined on Object.prototype
that calls Object.getPrototypeOf
.
Your confusion is caused by fact that Object.getPrototypeOf(Animal) === Function.prototype
(all functions are instances of Function
) and Function constructor/prototype is twisted.
Function.prototype === Function.__proto__; // true
typeof Function.prototype; // "function"
Upvotes: 0
Reputation: 613
This is how Javascript lookup chain works.
First note that
Animal.__proto__ === Function.prototype \\true
Animal.__proto__.constructor === Function \\true
Because for any function A
,
A.prototype.constructor === A
Then the question becomes, what is the __proto__
property of Function
? It is Function.prototype
.
Function.__proto__ === Function.prototype \\true
This is somehow weird because these two properties are not usually the same.
Usually, when a = new A();
a.__proto__ === A.prototype \\true
An instance's __proto__
property equals its constructor's prototype
;
But consider that every function is the instance of Function
and Function
itself is a function too. Function
is the constructor of itself!
Function.constructor === Function //true
It makes more sense now.
Now we look back at the question.
Animal.__proto__.constructor.__proto__.test = 28;
is equvalent to:
Function.__proto__.test = 28;
is equvalent to:
Function.prototype.test = 28;
So it is now clear that the two console.log
print out the same because:
Animal.__proto__ === Function.prototype \\ture
As we said at the very beginning.
Upvotes: 1
Reputation: 664971
You already know that Object.getPrototypeOf(Animal)
(or Animal.__proto__
) is the Function.prototype
object. So let's drop that Animal
thing and just repeat your equations with Function.prototype
:
Function.prototype.constructor.__proto__ == Function.prototype.constructor.prototype // true
Function.prototype.constructor.__proto__ == Function.prototype // true
Now, the .constructor
property of Function.prototype
(like for all well-defined prototype objects) points to its respective constructor, the Function
constructor function. So we've got
Function.__proto__ == Function.prototype // true
Function.__proto__ == Function.prototype // true
Now, given that Function
is a function, it only makes sense that it inherits from Function.prototype
like all other functions do.
This is what your testing confirms, as you basically did
Function.__proto__.test = 28;
Function.__proto__.test // 28
Function.prototype.test // 28
And yes, Function.test
and Animal.test
would yield 28
as well now.
Upvotes: 3