Summary and in-depth understanding of the four inheritance methods of javascript

Source: Internet
Author: User

JavaScript is a very free language, without the restrictions of a strong type of language, there are often many ways to implement a function. Inheritance is one of them. Inheritance in js can be divided into four categories. The previous article also mentioned some. Next, let's talk about the inheritance of js in detail.

1. Prototype inheritance-the simplest and most commonly used

      
Function funcA (){
This. show = function (){
Console. log ("hello ");
    }
}
Function funcB (){

}
FuncB. prototype = new funcA ();
Var B = new funcB ();
B. show ();


Here we use the features of the prototype chain, and the disadvantages are also obvious. If there are many inheritance layers, modifying the prototype at the top will affect all the objects below.

2. Prototype impersonating:


Function funcA (age ){
This. name = "xiaoxiao ";
This. age = age;
This. show = function (){
Console. log (this. name + this. age)

    }
}
Function funcB (){
This. parent = funcA;
This. parent (40 );
Delete this. parent;

}
Var B = new funcB ();
B. show ();


This inheritance method is easy to understand, but the code in funcA is obtained and executed in funcB, which can be interpreted:

Function funcA (age ){
This. name = "xiaoxiao ";
This. age = age;
This. show = function (){
Console. log (this. name + this. age)

    }
}
Function funcB (){
// This. parent = funcA;
// This. parent (40 );
// Delete this. parent;
// In fact, the above process is not just to move funcA
This. name = "xiaoxiao ";
This. age = age;
This. show = function (){
Console. log (this. name + this. age)

    }

}
Var B = new funcB ();
B. show ();


3. call and apply

I have mentioned this in the previous article and also explained the reasons in detail. I believe it is so easy to understand the prototype carefully.

Let's talk about the code below:

Function funcA (){
This. show = function (str ){
Console. log (str );
    }
}
Function funcB (){
This. read = function (){}
}
Var a = new funcA ();
Var B = new funcB ();
FuncA. call (B); // use call
A. show ("");
B. show ("B ");


The call and apply effects are the same, but they are different in passing parameters. However, call is recommended because the apply efficiency is much lower.

4. Copy inheritance

Function funcA (){
This. name = "hello ";
This. show = function (){
Console. log (this. name );
    }
}
Function funcB (){
This. extend = function (o ){
For (var p in o ){
This [p] = o [p];
        }
    }
}
Var a = new funcA ();
Var B = new funcB ();
B. extend ();
B. show ();

This is similar to the extend method of jquery. The principle is to traverse the attributes in a to B.



JavaScript inheritance methods


Concept of js inheritance

The following two inheritance methods are commonly used in js:

Prototype chain inheritance (inheritance between objects)
Class inheritance (inheritance between constructors)

JavaScript is not as object-oriented as java does. js is object-based and has no class concept. Therefore, to implement inheritance, you can use the prototype mechanism of js or the apply and call methods.

In the object-oriented language, we use classes to create a custom object. However, if everything in js is an object, how can we create a custom object? This requires the js prototype:

We can simply regard prototype as a template, and the newly created custom object is a copy of this template (prototype) (actually not a copy but a link, but this link is invisible, the new instantiated object contains an invisible _ Proto _ pointer pointing to the prototype object ).

Js can simulate and implement the class functions through constructor and prototype. In addition, the implementation of js class inheritance relies on the prototype chain.

Original type inheritance and class inheritance

Class inheritance refers to calling a super-type constructor within a sub-type constructor.
Strict class inheritance is not very common and is generally used in combination:

Function Super (){
This. colors = ["red", "blue"];
}

Function Sub (){
Super. call (this );
}

The original type inheritance creates a new object with an existing object, and points the prototype of the subclass to the parent class, which is equivalent to adding the prototype chain of the parent class.

Prototype chain inheritance

To make the subclass inherit the attributes of the parent class (including methods), you must first define a constructor. Then, assign the new instance of the parent class to the prototype of the constructor. The code is as follows:

<Script>
Function Parent (){
This. name = 'Mike ';
    }

Function Child (){
This. age = 12;
    }
Child. prototype = new Parent (); // Child inherits Parent, forming a chain through prototype

Var test = new Child ();
Alert (test. age );
Alert (test. name); // Get the inherited attribute
// Continue prototype chain inheritance
Function Brother () {// brother construction
This. weight = 60;
    }
Brother. prototype = new Child (); // continue prototype chain inheritance
Var brother = new Brother ();
Alert (brother. name); // inherits Parent and Child.
Alert (brother. age); // 12
</Script>

The inheritance of the prototype chain is still lacking, that is, the Object. All constructors inherit from the Object. The inheritance Object is automatically completed and does not need to be manually inherited. What is their subordination?

Determine the relationship between the prototype and the instance

You can determine the relationship between the prototype and the instance in two ways. Methods of the instanceof and isPrototypeof () operators:

Alert (brother instanceof Object) // true
Alert (test instanceof Brother); // false, test is the super class of brother
Alert (brother instanceof Child); // true
Alert (brother instanceof Parent); // true

Any prototype that has appeared in the prototype chain can be said to be the prototype of the instance derived from the prototype chain. Therefore, the isPrototypeof () method returns true.

In js, the inherited function is called a super type (parent class, the base class is also a row), and the inherited function is called a child type (subclass, derived class ). There are two main problems with prototype inheritance:
First, the literal rewriting prototype will interrupt the relationship, use the prototype of the reference type, and the child type cannot pass parameters to the Super type.

The pseudo-class solves the problem of reference sharing and super-type parameter passing. We can use the "borrow constructor" technology.

Borrow constructors (class inheritance)

<Script>
Function Parent (age ){
This. name = ['Mike ', 'Jack', 'Smith'];
This. age = age;
    }

Function Child (age ){
Parent. call (this, age );
    }
Var test = new Child (21 );
Alert (test. age); // 21
Alert (test. name); // mike, jack, smith
Test. name. push ('Bill ');
Alert (test. name); // mike, jack, smith, bill
</Script>

Although the borrow constructor solves the two problems just now, if there is no prototype, there is no way to reuse it. Therefore, we need the prototype chain + borrow constructor mode. This mode is called combination inheritance.

Combination inheritance

<Script>
Function Parent (age ){
This. name = ['Mike ', 'Jack', 'Smith'];
This. age = age;
    }
Parent. prototype. run = function (){
Return this. name + 'are both '+ this. age;
};
Function Child (age ){
Parent. call (this, age); // impersonate an object and pass parameters of the super type
    }
Child. prototype = new Parent (); // prototype chain inheritance
Var test = new Child (21); // write new Parent (21).
Alert (test. run (); // mike, jack, smith are both21
</Script>

Combined inheritance is a common inheritance method. The idea behind it is to use prototype chain to inherit prototype attributes and methods, the constructor is used to inherit instance attributes. In this way, function reuse is realized by defining the method on the prototype, and each instance has its own attributes.

Call (): call a method of an object to replace the current object with another object.

Call ([thisObj [, arg1 [, arg2 [, [,. argN])

Original type inheritance

This inheritance creates a new object based on an existing object with the help of the prototype, and does not need to create a custom type. It is called the original type inheritance.

<Script>
Function obj (o ){
Function F (){}
F. prototype = o;
Return new F ();
     }
Var box = {
Name: 'trigger4 ',
Arr: ['Brother ', 'Sister', 'Baba']
};
Var b1 = obj (box );
Alert (b1.name); // trigkit4

B1.name = 'Mike ';
Alert (b1.name); // mike

Alert (b1.arr); // brother, sister, baba
B1.arr. push ('parents ');
Alert (b1.arr); // brother, sister, baba, parents

Var b2 = obj (box );
Alert (b2.name); // trigkit4
Alert (b2.arr); // brother, sister, baba, parents
</Script>

The original type inheritance first creates a temporary constructor in the obj () function, then uses the input object as the prototype of the constructor, and finally returns a new instance of this temporary type.

Parasitic inheritance

This inheritance method combines the original type with the factory mode to encapsulate the creation process.

<Script>
Function create (o ){
Var f = obj (o );
F. run = function (){
Return this. arr; // share the reference.
};
Return f;
    }
</Script>

Small issues of combined inheritance

Combined inheritance is the most commonly used inheritance mode in js, but the super type of the combination inheritance is called twice during use; one is when the child type is created, the other is inside the subtype constructor.

<Script>
Function Parent (name ){
This. name = name;
This. arr = ['elder brother', 'Sister', 'parage'];
    }

Parent. prototype. run = function (){
Return this. name;
};

Function Child (name, age ){
Parent. call (this, age); // The second call
This. age = age;
    }

Child. prototype = new Parent (); // The first call
</Script>

The above code is the original combination inheritance, so the parasitic combination inheritance solves the problem of two calls.

Parasitic combined inheritance

<Script>
Function obj (o ){
Function F (){}
F. prototype = o;
Return new F ();
    }
Function create (parent, test ){
Var f = obj (parent. prototype); // create an object
F. constructor = test; // enhancement object
    }

Function Parent (name ){
This. name = name;
This. arr = ['Brother ', 'Sister', 'parents'];
    }

Parent. prototype. run = function (){
Return this. name;
};

Function Child (name, age ){
Parent. call (this, name );
This. age = age;
    }

InheritPrototype (Parent, Child); // implement inheritance here

Var test = new Child ('trigger4', 21 );
Test. arr. push ('Nephew ');
Alert (test. arr );//
Alert (test. run (); // only the method is shared.

Var test2 = new Child ('Jack', 22 );
Alert (test2.arr); // reference the problem to solve
</Script>

Call and apply

The global functions apply and call can be used to change the point of this in the function, as follows:

// Define a global function
Function foo (){
Console. log (this. fruit );
    }

// Define a global variable
Var fruit = "apple ";
// Customize an object
Var pack = {
Fruit: "orange"
};

// Equivalent to window. foo ();
Foo. apply (window); // "apple", this equals to window
// This = pack in foo
Foo. apply (pack); // "orange"

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.