Class inheritance can be implemented using a technique called prototype chain. So an object can be traced back to its ancestor(s) using a
prototype instance that is embedded (i.e.,
__proto__) in it, like a gene. For the end purpose of inheritance, i.e., code reusing, prototype chain also enables the accessing of members that only exist in ancestors, hence whenever such a member (method or property) is accessed, the runtime will check upwards the prototype chain that contains members information of the whole inheritance (sub-)tree.
Phew, it’s hard to explain coding concept without code. So next I am going to implement this prototype chain step by step. Moreover, I make it a trial and error process in hope that the read can simulate a real developing experience, and which I hope can be remembered (by you) easier.
Uncaught TypeError: subobj.amethod is not a function
Though the type can be recognized by the runtime, the properties can not be accessed as expected. So I think we need to call the super class constructor to initialize the missing properties. Let’s give it a go.
Unfortunately, the result is the same. Hmmm, this time is the corrupted
this in the superclass constructor. If this is not your first reaction, please ⬅ to my previous post that is dedicated to this topic.
In order to fix
this, we can either add:
, as per discussed in the post. I will use the second method because, well, it’s one line less:
Finally we nailed it! Are we? No:
In fact, we just made something else but inheritance, which does not exist in real world. I tentatively call it coupling. Though we made a wrong decision from the very first step, still the other effort we made can be largely reused. I’ve heard versions of stories about one guy, who failed a kickstart project, one day realized the pain eventually paid off in some other way. This is just like that. So let’s keep up.
In common (and correct) practice, prototype chain is established using two entities, an intermediate class (which is also an object, first class) and an intermediate object (,normal) in order to decouple the “thing” we made just now, and the designated object relation is given below:
in which, the intermediate object is an instance of the intermediate class.
Let’s get back to the snippet I showed in the beginning of my last post:
I hope the above text has made the above function clear now. Then let’s verify the function in code:
A better version of the
inherits() can be implemented using
Object.create() that can simplify the creation of the intermediate entities.
To be honest, I am feeling a bit exciting when checking the result:)
Wait, there is one last piece, what is a
You may have noticed, I stealthily added the constructor related code from here and omit the explanation. I did it on purpose in order to make the logic flow smooth. Now let’s scrutinize it:
prototype.constructor is a special method referring to the class itself. Normally the link is made by the runtime,
However, the original
ChildClass.prototype.constructor is broken when we chained up the
So we need to assign it back to