The basic idea of prototype chain inheritance is to let a prototype object point to an instance of another type
function SuperType() { this.property = true } SuperType.prototype.getSuperValue = function () { return this.property } function SubType() { this.subproperty = false } SubType.prototype = new SuperType() SubType.prototype.getSubValue = function () { return this.subproperty } var instance = new SubType() console.log(instance.getSuperValue()) // true
The code defines two types, SuperType and SubType, each type has an attribute and A method, SubType inherits SuperType, and inheritance is achieved by creating an instance of SuperType and assigning the instance to SubType.prototype.
The essence of the implementation is to rewrite the prototype object and replace it with an instance of a new type. Then all the properties and methods that exist in the instance of SuperType now also exist in SubType.prototype.
We know that when creating an instance, there will be an internal pointer in the instance object pointing to the prototype that created it, and it will be associated. Here the code SubType.prototype = new SuperType() will also be in SubType .prototype creates an internal pointer that associates SubType.prototype with SuperType.
So instance points to the prototype of SubType, and the prototype of SubType points to the prototype of SuperType. Then when the instance calls the getSuperValue() method, it will continue to look up along this chain.
Add method
When adding a method to the SubType prototype, if the parent class also has the same name, SubType will override this method to achieve the purpose of re-creation . But this method still exists in the parent class.
Remember not to add it in the form of a literal, because as mentioned above, instance inheritance is essentially rewriting. If you use the literal form again, it is another rewrite, but this time the rewrite is not followed by There is no association with the parent class, so the prototype chain will be truncated.
function SuperType() { this.property = true } SuperType.prototype.getSuperValue = function () { return this.property } function SubType() { this.subproperty = false } SubType.prototype = new SuperType() SubType.prototype = { getSubValue:function () { return this.subproperty } } var instance = new SubType() console.log(instance.getSuperValue()) // error
Problem
The main problem when simply using prototype chain inheritance comes from prototypes that contain reference type values.
function SuperType() { this.colors = ['red', 'blue', 'green'] } function SubType() { } SubType.prototype = new SuperType() var instance1 = new SubType() var instance2 = new SubType() instance1.colors.push('black') console.log(instance1.colors) // ["red", "blue", "green", "black"] console.log(instance2.colors) // ["red", "blue", "green", "black"]
The SuperType constructor defines a colors attribute. When SubType is inherited through the prototype chain, this attribute will appear in SubType.prototype, just like SubType.prototype.colors is specially created, so it will cause All instances of SubType will share this attribute, so if instance1 modifies the reference type value of colors, it will also be reflected in instance2.
The above is the detailed content of Example analysis of JavaScript prototype chain addition methods and problems that arise. For more information, please follow other related articles on the PHP Chinese website!