JavaScript prototypes inherit easy-to-ignore errors

Source: Internet
Author: User

JavaScript developers know that although JS does not have a class (ES6 added class syntax), but can simulate the OOP language class and object-oriented concepts, such as we all know a word, JavaScript everywhere is an object, and object-oriented language features are inherited, Encapsulation, polymorphism, abstraction, and this article is about JavaScript inheritance, JavaScript inheritance,prototype inheritance, combination inheritance, parasitic inheritance, and so on, in the daily development, which way of inheritance is better used in the developer of the results of the program and performance considerations. The author lists the errors that are often overlooked in the inheritance of prototypes.

Common Error One:

    

functionFa (name) { This. name=name; } Fa.prototype.myname=function(){//set up a prototype method for FAConsole.log ( This. Name); }                functionSon (name) {Fa.call ( This, name);//The this display of FA is bound to son, here the This shows the binding mechanism followed by the author will update} son.prototype=fa.prototype;//Referencing the prototype object of son to the prototype object of FA is actually a pointer concept in C + +, directly pointing to the prototype of FA.                //NOTE!!!!! : When you modify Son.prototype's constructor

Son.prototype.constructor=son; //This causes the constructor of the object created by FA to also point to son, which makes the object's type confusing .Son.prototype.sayhello=function(){//set up son's prototype methodConsole.log ("This is son"); }//Create Objectvarson=NewSon ("Son"); Son.sayhello (); //"This is son"Console.log (son); varHasNewFA ("FA"); Fa.sayhello (); //"This is son"Console.log (FA); //It is found here that the SayHello method is also present in the object created by FA, because Son.prototype directly references the Fa.prototype //Son.prototype=fa.prototype; does not create a new object that is associated to the Son.prototype, it only//is to let Son.prototype directly refer to the Fa.prototype object. So when you do something like Son.prototype.//SayHello = ... The Fa.prototype object itself is also modified directly by the assignment statement. Obviously it's not the knot you want.//If you don't need a Son object, you can use FA directly, and the code will be simpler.

Common error Two:

functionFa (name) { This. name=name; } Fa.prototype.myname=function() {Console.log ( This. Name); }                functionSon (name) {Fa.call ( This, name); } Son.prototype=NewFA ("FA");//Call FA's constructor new to Son.prototypeSon.prototype.sayhello=function() {Console.log ("This is son"); }                varson=NewSon ("Son");        Console.log (son);  Son.myname (); //son        varHasNewFA ("FA"); Console.log (FA);Fa.sayhello ();//here will be an error. Uncaught TypeError:fa.sayhello is not a function        //we found that the method created at son's prototype did not affect the prototype of FA. But after son.prototype = new Fa (),//var son=new son ("Son"); the value of our output son.name is son, there is a FA instance object on the prototype, and this instance object also has the Name property    //The output son is an implicit mask on the prototype chain, and the properties of this layer mask the value of the same property on the previous layer.                 //Son.prototype = new Fa () does create an object that is associated to the Son.prototype. But it uses//The "constructor call" of Fa (..), if the function Foo has some side effects (such as writing log, modifying state, note//other objects, add data attributes to this, and so on) will affect the "descendants" of Son () and the consequences//the unthinkable will make the prototype bloated.        

Correct practice:

functionFa (name) { This. name=name; } Fa.prototype.myname=function() {Console.log ( This. Name); }                functionSon (name) {Fa.call ( This, name); }

Son.prototype=object.create (Fa.prototype); //pay attention to this sentence //When you modify son's prototype. Son's constructor also points to FA, which needs to be manually modified constructor //ES6 Method Property Descriptor//ie8 is incompatible with the followingObject.defineproperty (Son.prototype, "constructor", {writable:true,//Read- Write property, False is readonly and cannot be modified by the outside worldConfigurable:true, //configuration property, False, the outside world cannot delete the property, such as delete Son.prototype.constructor will fail in strict mode will be error
Enumerablefalse, //enumeration property, which is false at this time, is not enumerated in the external for-in Access method, which is true;Value:son//associating constructor to son }); varson=NewSon ("Son"); Console.log (son); Son.myname (); Console.log (soninstanceofSon);//true //the core part of this code is the statement son.prototype = Object.create (Fa.prototype). Called//object.create (..) creates a "new" object in thin Air and associates the Prototype inside the new object to your//the specified object (in this case, Fa.prototype). //In other words, this statement means: "Create a new Son.prototype object and associate it to FA."//prototype ".

Here's a comparison of three ways:

    

It's not the same as the mechanism you want!
Son.prototype = Fa.prototype;
Basically meet your needs, but may have some side effects:(
Son.prototype = new Fa ();

   

Use Object.create (..) instead of using a secondary

Effect of Fa (..). The only downside to this is the need to create a new object and discard the old object, not
Modifies the existing default object directly.


It would be nice to have a standard and reliable way to modify the prototype association of an object. Before the ES6,
We can only do this by setting the. __proto__ property, but this method is not standard and is not compatible with all
Browser. ES6 added auxiliary functions object.setprototypeof (..), which can be repaired in a standard and reliable way.
Change the association.

  

ES6 need to discard the default Son.prototype before
Son.ptototype = Object.create (Fa.prototype);


ES6 can begin to modify the existing son.prototype directly.
Object.setprototypeof (Son.prototype,fa.prototype);


If you ignore the slight performance penalty of the Object.create (..) method (discarded objects need to be garbage collected)
It is actually shorter and more readable than the ES6 and its subsequent methods. But anyway, this is the end of two
A whole different syntax.

The above is the author of the prototype inheritance often ignored errors and better solutions, as for the parasitic inheritance and other methods are not the scope of this article, the subsequent author will also update the method of parasitic inheritance, if you ignore these details of errors, the results of subsequent programs will also produce some unpredictable results, Details determine success or failure.

JavaScript prototypes inherit easy-to-ignore errors

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.