Prototype method:
What does the prototype attribute mean? Prototype is the prototype. Every object (defined by function) has a default prototype property, which is an object type.
And this default attribute is used to realize the upward search of the chain. This means that if an attribute of an object does not exist, the attribute will be found through the object to which the prototype attribute belongs. What if prototype cannot be found?
js will automatically find the object to which the prototype attribute of the prototype belongs, so that the index will be searched up through the prototype until the attribute is found or the prototype is finally empty ("undefined");
//父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ this.feature = ['beard','strong']; } man.prototype = new person(); var one = new man(); console.log(one.feature); //['beard','strong'] console.log(one.hair); //black console.log(one.eye); //black console.log(one.skin); //yellow console.log(one.view()); //black,black,yellow
This method is the simplest. You only need to assign the prototype attribute value of the subclass to an inherited instance, and then you can directly use the methods of the inherited class.
For example, in the one.view() method in the above example, js will first check whether there is a view() method in the one instance. Because there is not, it looks for the man.prototype attribute, and the value of prototype is person. An instance,
This instance has a view() method, so the call is successful.
Apply method:
//父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ // person.apply(this,new Array()); person.apply(this,[]); this.feature = ['beard','strong']; } var one = new man(); console.log(one.feature); //['beard','strong'] console.log(one.hair); //black console.log(one.eye); //black console.log(one.skin); //yellow console.log(one.view()); //black,black,yellow
Note: If the apply parameter is empty, that is, no parameters are passed, pass new Array( ), [] to pass, null is invalid.
call method:
//父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ // person.apply(this,new Array()); person.call(this,[]); this.feature = ['beard','strong']; } man.prototype = new person(); var one = new man(); console.log(one.feature); //['beard','strong'] console.log(one.hair); //black console.log(one.eye); //black console.log(one.skin); //yellow console.log(one.view()); //black,black,yellow
The implementation mechanism of the call method requires one more man.prototype = new person(); What?
That's because the call method only implements method replacement and does not copy object attributes.
The inheritance of google Map API uses this method.
The implementation of the three inheritance methods is summarized above. But each method has its pros and cons.
If the parent class is like this:
//父类 function person(hair,eye,skin){ this.hair = hair; this.eye = eye; this.skin = skin; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } }
How should the subclass be designed so that the subclass man can pass parameters to the parent class person when creating the object? , the inheritance method of prototype is not applicable,
must use the apply or call method:
//apply方式 //子类 function man(hair,eye,skin){ person.apply(this,[hair,eye,skin]); this.feature = ['beard','strong']; } //call方式 //子类 function man(hair,eye,skin){ person.call(this,hair,eye,skin); this.feature = ['beard','strong']; }
But there are still disadvantages to using the apply method, why? In js, we have a very important operator called "instanceof", which is used to compare whether an object is of a certain type.
For this example, in addition to the man type, the one instance should also be of the person type. However, after inheriting in the apply method, one does not belong to the person type, that is, the value of (one instanceof person) is false.
After all this, the best inheritance method is the call+prototype method. After that, you can try whether the value of (one instanceof BaseClass) is true.
The third inheritance method also has flaws: when subclassing a new object, you need to pass the parameters required by the parent class, and the properties and methods in the parent class will be reproduced. The following inheritance method is is perfect:
function Person(name){ this.name = name; } Person.prototype.getName = function() { return this.name; } function Chinese(name, nation) { Person.call(this, name); this.nation = nation; } //继承方法 function inherit(subClass, superClass) { function F() {} F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass.constructor; } inherit(Chinese, Person); Chinese.prototype.getNation = function() { return this.nation; }; var p = new Person('shijun'); var c = new Chinese("liyatang", "China"); console.log(p); // Person {name: "shijun", getName: function} console.log(c); // Chinese {name: "liyatang", nation: "China", constructor: function, getNation: function, getName: function} console.log(p.constructor); // function Person(name){} console.log(c.constructor); // function Chinese(){} console.log(c instanceof Chinese); // true console.log(c instanceof Person); // true
The above is the detailed content of Detailed examples of the advantages and disadvantages of prototype, apply, and call methods in JavaScript. For more information, please follow other related articles on the PHP Chinese website!