JavaScript inheritance detailed and sample code _javascript tips

Source: Internet
Author: User

Some knowledge at that time really did not understand words, can put aside, stay in later to see perhaps can understand.

A few months ago, holding the "JavaScript Advanced Program Design (third edition)", after chewing the creation of objects, began to chew the inheritance, but after the prototype chain is really can't see, the brain more and more messy, and then threw it aside, continue to see the back. Now use this summer to understand this inheritance, the notes are sorted out.

Prototype chain (Prototype chaining)

Read an article first, the author of the article is very good, and also with a set of HD map Oh. lol ...

Links: [Learn notes] small angle to see JS prototype chain

Pick a few sentences from the original text

    1. The constructor accesses the prototype object through the prototype property
    2. The instance object accesses the prototype object through the [[prototype]] internal property, and the browser implements the Proto property for instance object access to the prototype object
    3. All objects are instances of object, and all functions are instances of function
    4. Object is a constructor, since it is a function, then it is an instance object of the function; The function is a constructor, but Function.prototype is an object and, since it is an object, an instance object of object

Determine the relationship between a prototype and an instance

There are two ways to detect the relationship between a prototype and an instance:

Instanceof: Determine if the object is an instance of another object

The internal operation mechanism of instanceof is as follows:

Functioninstance_of (l, R) {//l represents the left expression, R represents the right expression
Varo = r.prototype;//Fetch R's display prototype
 L = l.__proto__;//The implicit prototype of L =
WH Ile (True) {
if (L ===null)
returnfalse;
if (o = = L)//Here The emphasis: when O is strictly equal to L, return true
returntrue;
 L = l.__proto__; 
 } 
}

The above code is excerpted from: JavaScript instanceof operator In-depth analysis

isPrototypeOf (): Test whether an object exists on the prototype chain of another object
See the differences between the two methods: JavaScript isprototypeof vs instanceof usage

Using only the prototype chain to implement inheritance

Disadvantages: 1. The prototype property of the reference type value is shared by the instance; 2. You cannot pass arguments to a superclass constructor when you create an instance of a subtype

Functionfather () {
this.name = "Father";
This.friends = [' aaa ', ' BBB '];
}
Functionson () {
}
Son.prototype = Newfather ();
Son.prototype.constructor = Son;

Vars1 =newson ();
Vars2 =newson ();

Console.log (s1.name);//Father
Console.log (s2.name);//father S1.name
= "Son";
Console.log (s1.name);//son
Console.log (s2.name);//Father

Console.log (s1.friends);//["AAA", "BBB"]
Console.log (s2.friends);//["AAA", "BBB"]
s1.friends.push (' CCC ', ' ddd ');
Console.log (s1.friends);//["AAA", "BBB", "CCC", "DDD"]
console.log (s2.friends);//["AAA", "BBB", "CCC", "DDD"]

Using constructors to implement inheritance only

Implementation method: Calls the superclass constructor inside the subtype constructor (using the Apply () and call () methods)

Benefits: Solves the problem of referencing type attributes in prototypes, and subclasses can pass parameters to the superclass

Disadvantage: A subclass instance cannot access the method defined in the parent class (superclass) prototype, so functional reuse is not possible.

Functionfather (name,friends) {
this.name = name;
This.friends = friends;
}
Father.prototype.getName = function () {
returnthis.name;
};

Functionson (name) {
//NOTE: To ensure that the Father constructor does not override the properties of the Son constructor, place the code that calls the Father constructor in front of the property defined in the Son.
 Father.call (this,name,[' AAA ', ' BBB ']);

This.age =22;
}

Vars1 =newson (' Son1 ');
Vars2 =newson (' Son2 ');

Console.log (s1.name);//Son1
Console.log (s2.name);//Son2

S1.friends.push (' CCC ', ' ddd ');
Console.log (s1.friends);//["AAA", "BBB", "CCC", "DDD"]
console.log (s2.friends);//["AAA", "BBB"]

// A subclass instance cannot access a method S1.getname () in a parent class prototype
();//TypeError:s1.getName is not a function
s2.getname ();//TypeError: S2.getname is not a function

Combined inheritance (combination inheritance)

Implementation method: Using the prototype chain to implement the inheritance of the prototype properties and methods, and by borrowing the constructor to implement the inheritance of the instance property.

Functionfather (name,friends) {
this.name = name;
This.friends = friends;
}
Father.prototype.money = "100k $";
Father.prototype.getName = function () {
console.log (this.name);
};

Functionson (name,age) {
//inherits the attributes of the parent class
 Father.call (this,name,[' AAA ', ' BBB ']);

This.age = age;
}

Inheritance of properties and methods in the parent prototype
Son.prototype = Newfather ();
Son.prototype.constructor = Son;

Son.prototype.getAge = function () {
console.log (this.age);
};

Vars1 =newson (' Son1 ');
S1.friends.push (' CCC ');
Console.log (s1.friends);//["AAA", "BBB", "CCC"]
Console.log (S1.money);//100k $
s1.getname ();//Son1
s1.getage ();//

vars2 =newson (' Son2 ',);
Console.log (s2.friends);//["AAA", "BBB"]
Console.log (S2.money);//100k $
s2.getname ();//Son2
S2.getage (); 24

Combinatorial inheritance avoids the unilateral use of prototype chains or constructors to implement inherited defects, incorporates their advantages and becomes the most commonly used inheritance pattern in JavaScript, but it is also flawed, and the defects of combinatorial inheritance are specifically mentioned later.

Prototype inheritance (Prototypal inheritance)

Implementing ideas: Create new objects based on existing objects with a prototype, without having to create a custom type.

To achieve this, the following function (obj) is introduced

Functionobj (o) {
functionf () {}
 f.prototype = O;
RETURNNEWF ();
}
Varperson1 = {
 name: "Percy",
 Friends: [' aaa ', ' BBB ']
};
Varperson2 = obj (person1);
Person2.name = "Zyj";
Person2.friends.push (' CCC ');

Console.log (person1.name);//Percy
Console.log (person2.name);//Zyj
Console.log (person1.friends); AAA "," BBB "," CCC "]
Console.log (person2.friends);//[" AAA "," BBB "," CCC "]
ECMAScript 5 by adding object.create () Method normalizes the stereotype inheritance. In the case of passing in a parameter, the Object.create () and obj () methods behave the same.

varperson1 = {
 name: "Percy",
 Friends: [' aaa ', ' BBB ']
};
Varperson2 =object.create (person1);
Person2.name = "Zyj";
Person2.friends.push (' CCC ');

Console.log (person1.name);//Percy
Console.log (person2.name);//Zyj
Console.log (person1.friends); AAA "," BBB "," CCC "]
Console.log (person2.friends);//[" AAA "," BBB "," CCC "]

You can choose to use this inheritance when you do not need to create a constructor selectmen and just want one object to remain similar to another object.

Parasitic inheritance (parasitic inheritance)

Parasitic inheritance is a kind of thinking which is closely related to the prototype inheritance.

The idea is to create a function that encapsulates only the inheritance process, which in some way enhances the object and finally returns the object.

Functionobj (o) {
functionf () {}
 f.prototype = O;
RETURNNEWF ();
}
Functioncreateperson (original) {//Encapsulate inheritance process
Varclone = obj (original);//Create object
 clone.showsomething = function () {/ /Enhanced Object
console.log ("Hello world!");
returnclone;//return Object
}

Varperson = {
 name: ' Percy '
};
Varperson1 = Createperson (person);
Console.log (person1.name);//Percy
person1.showsomething ();//Hello world!

Parasitic modular inheritance (parasitic combination inheritance)

Let's talk about the defects of our previous combination inheritance. The biggest problem with combinatorial inheritance is that, in any case, the constructor of the parent class is invoked two times: once it is the prototype of the subclass, and then the constructor of the parent class is called inside the subclass constructor, when the subclass constructor is invoked.

Functionfather (name,friends) {
this.name = name;
This.friends = friends;
}
Father.prototype.money = "100k $";
Father.prototype.getName = function () {
console.log (this.name);
};

Functionson (name,age) {
//inherits the attributes of the parent class
 Father.call (this,name,[' AAA ', ' BBB ']), and the second call to Father (), which is actually in the new Son () This.age = age is invoked

.

Inheritance of attributes and methods in the parent prototype
Son.prototype = Newfather (); The first call to Father ()
Son.prototype.constructor = Son;

The first call makes the prototype of a subclass into an instance of the parent class, thus the subclass's prototype gets the instance property of the parent class, and the second call causes the instance of the subclass to get the instance property of the parent class, and the instance property of the subclass, by default, masks the attribute with its name in the subclass prototype. Therefore, after these two calls, there are redundant attributes in the subclass prototype, which introduces the parasitic combined inheritance to solve this problem.

The idea behind parasitic modular inheritance is that instead of calling the constructor of the parent class in order to specify the subclass's prototype, all we need is a copy of the parent prototype.

In essence, you use parasitic inheritance to inherit the prototype of the parent class, and then return the result to the subclass's prototype.

 Functionobj (o) {functionf () {} f.prototype = O; Returnnewf ();} Functioninheritprototype (S  On,father) {varprototype = obj (father.prototype);//Create object prototype.constructor = Son;//Enhanced Object Son.prototype = prototype;
Return object} functionfather (name,friends) {this.name = name; this.friends = friends;}
Father.prototype.money = "100k $";

Father.prototype.getName = function () {console.log (this.name);};

Functionson (name,age) {//inherits the attributes of the parent class Father.call (this,name,[' AAA ', ' BBB ']);
This.age = age;

////using parasitic inheritance to inherit the properties and Methods Inheritprototype (Son,father) in the parent-class prototype;

Son.prototype.getAge = function () {console.log (this.age);};
Vars1 =newson (' Son1 ', 12);
S1.friends.push (' CCC '); Console.log (s1.friends);//["AAA", "BBB", "CCC"] Console.log (S1.money);//100k $ s1.getname (); Son1 S1.getage ();
Vars2 =newson (' Son2 ', 24); Console.log (s2.friends);//["AAA", "BBB"] Console.log (S2.money);//100k $ s2.getname (); Son2 S2.getage (); 

Advantage: The subclass prototype avoids inheriting unnecessary instance properties from the parent class.

The developers generally believe that parasitic modular inheritance is the ideal way to inherit based on type inheritance.

At last

Finally, two very hard articles are strongly recommended.

Javascript–how Prototypal Inheritance really works
JavaScript ' s Pseudo Classical inheritance diagram (need to flip the wall)

Pick up a hard picture of the second article:


After reading, seconds to understand the prototype chain, there is wood?

The above is the JavaScript inheritance of the data collation, follow-up continue to supplement the relevant information thank you for your support of this site!

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.