Understanding the prototype chain
In the world of JavaScript, functions are a one-class citizen.
The above sentence has been seen in many places. In my own words to understand is: function as father and mother . "When Dad" is because we use the function to deal with a variety of "menial dirty" (various tool functions, page interaction, business logic, etc.); "When Mom" is because the function also "children" (create object).
In the world of JavaScript, every object has a hidden __proto__ property. This property points to the prototype () of the constructor that generated the object prototype . in fact, all functions have a prototype . Consider the following example:
function Human(){}varH1= New Human()varH2= New Human()//H1 and H2 are all objects created by the human function (called Human instance objects), so:H1.__proto__ = Human.prototypeH2.__proto__ = Human.prototype//Human.prototype is an object (and is called a prototype object bar), so you can add some properties or methods to it, such as:Human.prototype.Legs = 2Human.prototype.Sleep = function(){ Console.Log(' sleeping ... ')}
This side also stipulates:
All instance objects have access to the properties and methods inside the corresponding prototype object. (Understanding the key to the prototype chain)
// 不难得出结论:h1.legs===2// trueh2.legs===2// trueh1.sleep// sleeping....h2.sleep// sleeping....
Don't ask me why I have access, I do not know, because the following person is so stipulated.
Implementing inheritance
Then look at another constructor:
function Coder(){}//If the prototype of human is assigned to the coder prototype hereCoder.prototype = Human.prototype//Then add some coder own prototype methods and propertiesCoder.prototype. Age = -Coder.prototype. Work = function(){ Console.Log(' Write code ')}//Create a new Coder objectvarC1= New Coder()//Not difficult to drawC1. Age === Coder.prototype. Age //TrueC1. Work === Code.prototype. Work //TrueC1.Legs === Human.prototype.Legs //True 2C1.Sleep === Human.prototype.Sleep //True
Jsfiddle
Although the prototype of the Human is assigned directly to the coder archetype to allow the coder instance to access the properties and methods on the Human prototype, it is obviously not what we expected if you would like to modify the coder prototype individually to affect the values on the Human prototype.
Coder.prototype.sleep=function{ console.log(‘still write code....‘)}// 修改了Coder的原型,但同时也会影响Human的原型// 因此需要修改Coder.prototype的指向从而避免这个问题Coder.prototype=// h1是Human的一个实例
So it should be written like this:
Coder.prototype=newHuman()// 或者Coder.prototype=Object.create(Human.prototype)// 实际上这两种写法还是有一定的区别
This enables JavaScript's simplest prototype chain inheritance.
However, there are two drawbacks to this writing:
A property (method) of a reference type in a parent class constructor is shared by all child class instances, so changing the properties (or methods) of one instance affects the properties (or methods) of all instances.
When you create a subclass instance, you cannot pass arguments to the parent class constructor.
So you need to call the parent constructor within the subclass constructor and bind the class this :
functionCoder{ Human.call(this, arg) // 接着再写自身的属性(方法)}
This is equivalent to overriding the parent constructor in the subclass constructor, and there is no "reference" problem. The above is the constructor inheritance.
Reference
6 ways to re-understand JS's inheritance
Prototype chains and inheritance in JavaScript