Prototype and prototype inheritance

Source: Internet
Author: User

JavaScript does not support inherited patterns of traditional classes, it is a prototype-based inheritance, that is, through prototype settings to implement inheritance

Let's consider the following question

  function   person () { this . Name = "haha" ;  this . Sayname = function   () {Console.log ( this  .name); }}  var  p1 = new  
   
     person ();  
    var  p2 = 
    new  
     person ();        P1.sayname (); Console.log (p1.sayname  = = = P2.sayname); 
    // 
    false  
   

When we use the constructor pattern (called by new function), we find that the methods within the constructor are created once in each instance, that is, to implement the same function to create two functions (the function is also an object, that is, when we create more instances, To inevitably create more objects of the same function, this does not conform to the idea of multiplexing)

To implement the problem of referencing a function (object) We can move the Sayname method above to the outside of the person construct and bind to a specific object when instantiated through this, which implements the same function (object) of different object references

function person () {this.name = "haha"; this.sayname = Sayname;} function Sayname () {console.log (this.name);} var p1 = new Person (), var p2 = new Person ();p 1.sayName ()//hahaconsole.log (p1.sayname = = = P2.sayname);//true

The way to solve the problem is also a big problem, that is 1) the function of the global role is only called by an object, it should be considered that the global function location is somewhat unreasonable (position a bit large) 2) when we want to define a lot of similar functions for person, Then this person does not exist what we call encapsulation, most of the methods it defines are exposed outside

And that leads to the prototype pattern.

Prototypes: Each function has a prototype (prototype) attribute, which is a pointer to an object that contains properties and methods that can be shared by all instances of a particular type, that is, prototype is the prototype object for which you created the instance.

Prototype mode

Here's a simple example.

            var animal = function () {This.type = "animal"; this.testtype = "Haha";} Animal.prototype.sayType = function () {console.log (this.type);};/ /Add a method to the animal prototype
var person = function () {this.type = ' person ';//Adds a new type in person, masks type}//in animal to add a property to person Person.prototype = new Animal ();//Set the prototype of person to point to (the same) Animal instance var a = new person (); A.saytype (); Console.log (A.testtype);
         
A[person instance]
{type: ' person '}
Person.prototype[animal instance]
{type: "Animal" Testtype: "Haah"}
Animal.prototype
{Function:saytype}
object.prototype//Default Prototypes
{}
            
      

A prototype of a object is an instance of animal, so a can access a property or method in a animal instance, and through an instance of animal accesses a property or method in a animal prototype, we can access the value saved in the prototype through an object instance. However, the value of the prototype cannot be overridden by an object instance, and if we add a property or method in the instance to the prototype, we create the property or method in this instance that masks the property or method in the prototype.

This is because the process of property lookup is looked up from the beginning of the instance along the prototype chain, and when the corresponding property is found, it returns if Object.prototype is found, and returns undefined

So when we just want to get the attributes from the instance, rather than get the properties from the prototype, we're going to pass the hasOwnProperty () method.

Disadvantage: The above mode of pointing the prototype attribute of an instance to another instance causes all properties in the prototype to be shared by the instance (pointing to the same instance) and we cannot pass parameters to the prototype (which will also cause problems of all instances of the same property) When the attribute of a reference type is present in this instance, it is possible to have unexpected results.

 function   Supertype () { Span style= "color: #0000ff;"        >this . Colors = ["Red", "green"  function   subtype () {} Su        Btype.prototype  = new   supertype ();  var  a = new   subtype ();  var  b = new   subtype ();        A.colors.push ( black "); Console.log (b.colors);//red Green Black 

Console.log (a instanceof subtype);//true
Console.log (a instanceof supertype);//true
Console.log (a instanceof Object);//true reflects the relationship between the instance and the prototype due to the relationship of the prototype chain, it can be said that a instance is an instance of the type appearing in the prototype chain.

The above example shows that when a prototype has a reference type in the object, modifying the value in one instance will also be affected (because the attribute is found in the prototype chain and does not exist in its own instance, so it will produce such a result)

Based on the above reasons, we seldom use a single prototype chain to implement inheritance ( the implementation mechanism of inheritance is to rewrite the prototype object )

In order to solve the problem of reference type in super-class prototype, the idea of using a schema (classic inheritance) to borrow a constructor is to call a super-type constructor in the context of a subtype, so that each subtype has its own copy of a super-type. It also has the advantage of passing arguments to a super-type constructor (that is, implementing a definition of a different subtype)

        functionsupertype (name) { This. Name =name;  This. colors = ["Red", "green"]; }        functionsubtype (name) {Supertype.call ( This, name); //You can add your own properties or methods here.            //the difference between call apply is that the form of the Apply pass parameter must be an array call that is passed in the form of multiple arguments        }        varA =NewSubtype ("Haha"); varb =NewSubtype ("Hao"); Console.log (a.name);//hahaConsole.log (B.name);//HaoA.colors.push ("Black"); Console.log (a.colors);//["Red", "green", "black"]Console.log (b.colors);//["Red", "green"]    

But there are some problems with the use of the constructor pattern. 1) Define a method in a constructor, there is a problem with multiplexing 2) methods defined in a super-type prototype are not visible to the child type

             function () {            console.log ("HI");        }

When we call the Sayhi method through a generated instance of a, we will report sayhi undefined (because we do not inherit through prototype, so we cannot access the Supertype property through the prototype chain)

This puts forward another pattern, that is, combinatorial inheritance (pseudo-classical inheritance), which is a pattern of combining borrowed and prototype chain technology, that is, to inherit the attribute by borrowing the construction pattern, and the prototype chain to inherit the properties and methods of the prototype.

functionsupertype (name) { This. Name =name;  This. colors = ["Red", "green"]; } SuperType.prototype.sayName=function() {Console.log ( This. Name); }        functionsubtype (name) {Supertype.call ( This, name); } Subtype.prototype=Newsupertype (); varA =NewSubtype ("Haha"); varb =NewSupertype ("Hao"); A.sayname ();//hahaB.sayname ();//HaoA.colors.push ("Black"); Console.log (a.colors);//["Red", "green", "black"]Console.log (b.colors);//["Red", "green",]

In such a pattern, an instance has a copy of its own prototype property, and it is also the most common inherited pattern to access the properties inherited from the prototype through the prototype chain.

Reference JavaScript Advanced Programming

Uncle Tom's Blog powerful prototype and prototype chain: http://www.cnblogs.com/TomXu/archive/2012/01/05/2305453.html

Prototype and prototype inheritance

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.