Discussion on the inheritance of JS (__JS)

Source: Internet
Author: User

Whenever we talk about JS inheritance, the first reaction in your head is to prototype the prototype mechanism to achieve it. But have you used other methods to implement inheritance, or do you understand the pros and cons of other implementations and various inheritance implementations?

OK, let's take a look at some of the more common inheritance implementations.

1, prototype way

var  baseclass  = function ()
   
     {this
   
       . Name  =   "3ZFP";
   
      this. Age  = M   ;
  
        this. ToString  =   function ()  {return this   . Name + '   "   + this. age;
  
    } 
 
 } 
  
  var  Derived  =   function ()
  
    {this 
  
      . Address  =   "Shenzhen";
 
 } 
 
 Derived.prototype  =   new  baseclass ();
 
 var  instance  =   new  Derived ();
 
 Instance. ToString ();


The easiest way to do this is to simply make the prototype of a class OK for an inherited instance, and then use the BaseClass method directly.

What does the prototype attribute mean? Prototype is a prototype, and each object (defined by function) has a default stereotype property, which is an object type. And the default property is used to implement the chain upward climb. This means that if an object's properties do not exist, that object's properties will be looked up by the object corresponding to the prototype property. If the prototype can't find it. JS will automatically find the corresponding object of the prototype prototype property to find, so that through the prototype has been climbed up the index until the property found or prototype finally empty ("undefined");

For example, the instance in the previous example. ToString () method. JS will first find in the instance instance whether there is a ToString () method, because there is no, so look for the Derived.prototype property, and prototype is an instance of Newclass, the instance has the ToString () method, The call succeeds and the instance Name property is also assigned to find the prototype to implement.

Note that each object is prototype by default to an object, but the object is not equal to object; Look at the following code:

        var  foo  =   function ()  {};
 
        var  result  =  


The result of this code value is false;

Here are a few points to note:

      typeof (Object.prototype)  = =   "Object";
   
  
  
        typeof (Object.prototype.prototype)  = =   "undefined";
  

 
       var  obj  =   new  Object ();
 
        typeof (Obj.prototype)  = =   "undefined";

      
 
         var  obj  =    {};
        typeof (Obj.prototype)  = =   "undefined";


2, apply the way

var  baseclass  = function ()
 
     {this
  
     . Name  =   "3ZFP";
  
     this. Age  = M   ;
 
       this. ToString  =   function ()  {return this   . Name + '   "   + this. age;
  
     } 
 
 } 
 
  var  Derived  =   function ()
 
    { 
  
        baseclass.apply (this, new  Array ());

     this. Address  =   "Shenzhen";
 
 } 
 
  var  instance  =   new  Derived ();
  
 Instance. ToString ();


In this way, what we need to understand most is the role of the Apply function.

The method is generally interpreted as replacing the B method with A method. The first parameter is the object itself of the B method, the second argument is an array, and the value in the array is the list of arguments that need to be passed to the A method, and Null is not valid if the argument is null, that is, if there is no parameter passing, the new array () is passed.

The General Way is:

In this case, however, the Apply method performs a two-step operation.

The first one is to instantiate the BaseClass with the array array as the initialization parameter.

Second : Copy all properties of the newly generated instance object (Name,age, ToString method) to the instance instance object. This enables inheritance.

var  foo  =   function ()
   
    {this
 
        . Fooa  =   function ()  {this
  
                . foob.apply (This, new< C11/>array ("sorry"));
 
        } 
 
         this. Foob  = function (str)
  
          {
 
               alert (str);
  
        } 
 
 } 
  
  New  foo (). Fooa ();


3, Call+prototype Way

var  baseclass  = function (name,age)
  
    {this

     . Name  =  name;
  
    this. Age  = Age  ;
  
      this. ToString  =   function ()  {return this   . Name + '   "   + this. age;
 
    } 
  
} 
 
 var  Derived  =   function ()
 
   { 
  
      Baseclass.call (this, "3ZFP");
 
    this. Address  =   "Shenzhen";
 
 } 
 
 Derived.prototype  =   new  baseclass ();
  
  var  instance  =   new  Derived ();
  
 Instance. ToString ();


In fact, the call function and the Apply method has a very similar role, are using a method to replace the B method, but the parameter transmission is not the same, the call method's first parameter is the B method of the object itself, and the parameter column and the array object packaging, direct transmission can be.

Why the function is similar, call Way's realization mechanism but wants one more derived.prototype = new BaseClass (); Statement. That's because the call method only implements the substitution of the method and does not copy the object attribute.

The call method actually does the following several things:

Cases:

var  foo  =   function ()
   
    {this
   
         . Fooa  =   function ()  {this
  
               . Foob.call (This, "sorry " );
 
      } 
  
       this. Foob  = function (str)
 
          {
 
              alert (str);
 
       } 
 
 } 
 
 New  foo (). Fooa ();

 


Then This.fooB.call (this, "sorry") performs the following actions: 1 this. temp = this. Foob;
2
3. Temp ("sorry");
4
5 Delete (this. temp);
6

In fact, the inheritance of the Google Map API is to use this approach. You can download the reference reference (maps.google.com).

4, Prototype.js in the implementation of the way

Object.extend  =   function (destination, source)   {for (property in  source)   {
  
     Destination[property]  =  source[property];
  
  } 
 
        return  destination;
 
 } 
  
  var  baseclass  = function (name,age)  {this
  
        . Name  =  name;
 
       this. Age  = Age  ;
  
         this. ToString  =   function ()  {return this   . Name + '   "   + this. age;
 
        } 
  
 } 
 
 var  Derived  = function ()
 
    {     
  
       Baseclass.call (this, "foo");
 
        this. Address  =   "singapore";
  
         this. ToString  =   function ()  {
 
              var  string  =  Derived.prototype.ToString.call (this);
 
               Return  string  + '   "+ this   . Address; 
  
 Object.extend (Derived.prototype, New  BaseClass ());
  
  var  instance  =   new  Derived ();
 
 


This way, in fact, is an explicit use of the principle of apply to achieve inheritance. First var temp = new BaseClass (), and then the property traversal of temp is copied into Derived.prototype. For (the property in source) represents all the properties that traverse an object. However, private properties cannot be traversed. Cases:

var  foo  =   function ()
 2  
 3    {
 4  
 5         var  innerstring  =   "";
 6  
 7 this         . Name  =   "3ZFP";
 8  
 9 this         . Age  = M   ;
A         function  innertostring ()                {  return innerstring;  var  f  = new  foo ();  var  eles  =   "";
For  
(property in  f)        eles = "   " + property;  
document.write (eles); 


The output is "name age" without "innerstring" and "innertostring ()"; The specific principle, which can be explained later (including private variables, private functions, variable accessibility of private functions, etc.). The above summarizes the implementation of various ways of inheritance. But each method has its advantages and disadvantages.

The first way, how to achieve the following requirements, need to show "3zfp__100";

var  baseclass  = function (name,age)
 2  
 3    {
 4  
 5 this      . Name  =  name;
 6  
 7 this      . Age  = Age  ;
 8  
 9 This       . ToString  =   function ()  {
a   . Name + "   "   + this. Age;
The  var  Derived  =   function (name,age)
This    . Address  =   "Shenzhen";  
Derived.prototype  =   new  baseclass ();  
MB  var  instance  =   new  Derived ("3ZFP");  
document.write (instance. ToString ());  
31  


We can find by running that the output is actually "undefined__undefined". This means that the name and age are not assigned values.

Oh,my god! Despair The second and third methods can be implemented, as follows:

 var baseclass = function (name,age) 2 3 {4 5 this. Name = name;
 6 7 this. Age = age; 8 9 this.
ToString = function () {A. Name + "" + this. age; The var Derived = function (name,age) is baseclass.apply (thi.)
S, New Array (Name,age));
this. Address = "Shenzhen";
MB var instance = new Derived ("3ZFP", 100); document.write (instance.
ToString ()); ______________________________________________--------------------------------------------------------      -------------var baseclass = function (name,age) {40-name = NAME = 41
this. Age = age; This is the only.
ToString = function () {A. Name + "" + this. age;  Derived var = function (Name,age) 52 53 {54
Baseclass.call (this, name,age);
this. Address = "Shenzhen";
Derived.prototype = new BaseClass ();
The var instance = new Derived ("3ZFP", 100); document.write (instance).
ToString ());   68 69 70


But the application method also has shortcomings, why. In JS, we have a very important operator that is "instanceof", which is used to compare whether a pair of pairs is of a certain type. For inheritance, we should be in addition to the derived type, but also the BaseClass type. The Apply method returns a value of False ((instance instanceof BaseClass) = = false). This problem can also occur because Prototype.js uses a similar method of apply.

Ah, the ultimate method is Call+prototype way, or Google Bull X. You can try it correctly ((instance instanceof baseclass) = = True).

Finally, it is multiple inheritance, because JS prototype can only correspond to one object, so can not achieve a real sense of multiple inheritance. A JS library simulates multiple inheritance, but the library also overrides the Instanceof method, using _instanceof and _subclassof functions to simulate judgments. The library's name is Modello.js, interested in the search can be downloaded.

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.