On a deeper understanding about proto and prototype
Last a few days, I just looked through some basic rules about prototype and __proto__. But today when I learnt how to implement the function call() by myself, I found that there’s something unclear.
1 | Function.prototype.myCall = function(ctx) { |
How to understand the third line? What does this refer to?
First, let’s recall how we use the function myCall.
1 | Function.prototype.myCall = function(ctx) { |
- a is a function
- a uses its method myCall.
Wait. As far as I’m concerned, only Object can has a method. But how could a function use a method?
So I looked through some information, and a picture can conclude it well.
- Everything in JS is Object. Function is an object, Function.prototype is an object. So they all share the same feature: they have a property: __proto__, which is a pointer to its constructor’s prototype.
- Function is a special object. Including general properties, it has an extra property: prototype, which has a property named constructor which is the Function itself.
So it’s easy for us to understand:
1 | Function.prototype.myCall = function(ctx) { |
So how do we understand the total process of the code?
First we define a method myCall for Function.prototype, then we define a function a, which is inherited from Function.prototype.
In the last line, we make the function a (also an object) call the method myCall. First it look up in a‘s properties, but cannot match, so it backtracks to a.__proto__ AKA Function.prototype. So it finally finds the method, and this refers to the object & function a.
Finally we revise the basic knowledge of prototype chain.
Object.prototype(top of the prototype chain)
Function.prototype inherited from Object.prototype
Function and Object inherited from Function.prototype.
There are some thoughts on the topic which is interestring.