Home > Web Front-end > JS Tutorial > Detailed explanation of inheritance in JavaScript_javascript skills

Detailed explanation of inheritance in JavaScript_javascript skills

WBOY
Release: 2016-05-16 16:14:30
Original
1116 people have browsed it

The 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)
Since js is not a truly object-oriented language like java, js is based on objects and has no concept of classes. Therefore, if you want to implement inheritance, you can use the prototype mechanism of js or the apply and call methods

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

We can simply think of prototype as a template. The newly created custom objects are all copies of this template (prototype) (actually not copies but links, but this link is invisible. New There is an invisible __Proto__ pointer inside the instantiated object, pointing to the prototype object).

JS can simulate the functions of classes through constructors and prototypes. In addition, the implementation of js class inheritance also relies on the prototype chain.

Prototypal inheritance and class inheritance

Classic inheritance is calling the constructor of the supertype inside the constructor of the subtype.
Strict class inheritance is not very common, and is usually used in combination:

Copy code The code is as follows:

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

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


Prototypal inheritance is to create new objects with the help of existing objects, and point the prototype of the subclass to the parent class, which is equivalent to joining the prototype chain of the parent class

Prototype chain inheritance

In order for the subclass to inherit the attributes (including methods) of the parent class, you first need to define a constructor. Then, assign the new instance of the parent class to the constructor's prototype. The code is as follows:

Copy code The code is as follows:

<script><br> Function Parent(){<br> This.name = 'mike';<br> } <p> function Child(){<br> This.age = 12;<br> }<br> Child.prototype = new Parent();//Child inherits Parent and forms a chain through the prototype</p> <p> var test = new Child();<br> alert(test.age);<br> ​​ alert(test.name);//Get the inherited attributes<br> //Continue prototype chain inheritance<br> Function Brother(){ //brother construction<br> This.weight = 60;<br> }<br> Brother.prototype = new Child();//Continue prototype chain inheritance<br> var brother = new Brother();<br> alert(brother.name);//Inherits Parent and Child, pops up mike<br> ​​ alert(brother.age);//pop-up 12<br> </script>

The above prototype chain inheritance is missing a link, that is Object. All constructors inherit from Object. Inheriting Object is done automatically and does not require us to inherit manually. So what is their affiliation?

Determine the relationship between prototype and instance

The relationship between prototypes and instances can be determined in two ways. Operator instanceof and isPrototypeof() methods:

Copy code The code is as follows:

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

As long as it is a prototype that appears in the prototype chain, it can be said to be the prototype of the instance derived from the prototype chain. Therefore, the isPrototypeof() method will also return true

In js, the inherited function is called the super type (parent class, base class is also acceptable), and the inherited function is called the subtype (subclass, derived class). There are two main problems with using prototypal inheritance:
First, literal overriding of the prototype will break the relationship and use the prototype of the reference type, and the subtype cannot pass parameters to the supertype.

Pseudo classes solve the problem of reference sharing and the inability to pass parameters of super types. We can use the "borrowed constructor" technology

Borrow constructor (class inheritance)

Copy code The code is as follows:

<script><br> Function Parent(age){<br> This.name = ['mike','jack','smith'];<br> This.age = age;<br> } <p> function Child(age){<br>         Parent.call(this,age);<br> }<br> var test = new Child(21);<br> alert(test.age);//21<br> ​​ alert(test.name);//mike,jack,smith<br> Test.name.push('bill');<br> ​​ alert(test.name);//mike,jack,smith,bill<br> </script>


Although borrowing constructors solves the two problems just mentioned, without a prototype, reuse is impossible, so we need a prototype chain to borrow constructors. This pattern is called combined inheritance

Combined inheritance

Copy code The code is as follows:

<script><br> Function Parent(age){<br> This.name = ['mike','jack','smith'];<br> This.age = age;<br> }<br> Parent.prototype.run = function () {<br>           return this.name ' are both' this.age;<br> };<br> Function Child(age){<br> ​​​ Parent.call(this,age);//Object impersonation, passing parameters to the super type<br> }<br> Child.prototype = new Parent();//Prototype chain inheritance<br> var test = new Child(21);//You can also write new Parent(21)<br> alert(test.run());//mike,jack,smith are both21<br> </script>

Combined inheritance is a commonly used inheritance method. The idea behind it is to use the prototype chain to inherit prototype properties and methods, and to borrow constructors to inherit instance properties. In this way, function reuse is achieved by defining methods on the prototype, and each instance is guaranteed to have its own attributes.

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

Copy code The code is as follows:

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

Prototypal inheritance

This kind of inheritance uses prototypes to create new objects based on existing objects without creating custom types. It is called prototypal inheritance

Copy code The code is as follows:

<script><br> Function obj(o){<br>           function F(){}<br>             F.prototype = o;<br>            return new F();<br> }<br> var box = {<br> name : 'trigkit4',<br> arr : ['brother','sister','baba']<br> };<br> var b1 = obj(box);<br> ​​ alert(b1.name);//trigkit4 <p> b1.name = 'mike';<br> alert(b1.name);//mike</p> <p> alert(b1.arr);//brother,sister,baba<br> b1.arr.push('parents');<br> alert(b1.arr);//brother,sister,baba,parents</p> <p> var b2 = obj(box);<br> ​​ alert(b2.name);//trigkit4<br> alert(b2.arr);//brother,sister,baba,parents<br> </script>

Prototypal inheritance first creates a temporary constructor inside the obj() function, then uses the incoming object as the prototype of this constructor, and finally returns a new instance of this temporary type.

Parasitic inheritance

This inheritance method combines the prototype factory pattern with the purpose of encapsulating the creation process.

Copy code The code is as follows:

<script><br> Function create(o){<br> var f= obj(o);<br>             f.run = function () {<br>                 return this.arr;//Similarly, the reference will be shared <br>         };<br>          return f;<br> }<br> </script>

Small problems with combined inheritance

Combined inheritance is the most commonly used inheritance pattern in js, but the supertype of combined inheritance will be called twice during use; once when creating the subtype, and the other time inside the subtype constructor

Copy code The code is as follows:

<script><br> Function Parent(name){<br> This.name = name;<br> This.arr = ['brother','sister','parents'];<br> } <p> Parent.prototype.run = function () {<br>          return this.name;<br> };</p> <p> function Child(name,age){<br>         Parent.call(this,age);//Second call<br> This.age = age;<br> }</p> <p> Child.prototype = new Parent();//First call<br> </script>

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

Parasitic Combinatorial Inheritance

Copy code The code is as follows:

<script><br> Function obj(o){<br>          function F(){}<br>           F.prototype = o;<br>           return new F();<br> }<br> Function create(parent,test){<br>         var f = obj(parent.prototype);//Create object<br>             f.constructor = test;//Enhancement object<br> } <p> function Parent(name){<br> This.name = name;<br> This.arr = ['brother','sister','parents'];<br> }</p> <p> Parent.prototype.run = function () {<br>          return this.name;<br> };</p> <p> function Child(name,age){<br>          Parent.call(this,name);<br> This.age =age;<br> }</p> <p> inheritPrototype(Parent,Child);//Inheritance is achieved through here</p> <p> var test = new Child('trigkit4',21);<br> Test.arr.push('nephew');<br> alert(test.arr);//<br> alert(test.run());//Only the method is shared</p> <p> var test2 = new Child('jack',22);<br> alert(test2.arr);//Quotation problem resolution<br> </script>

call and apply

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

Copy code The code is 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", at this time this is equal to window
//This in foo at this time === pack
foo.apply(pack); // "orange"

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template