How inheritance is implemented in JavaScript

Source: Internet
Author: User

JS in the implementation of inheritance and the traditional object-oriented language is different: the traditional object-oriented language inheritance is implemented by the class, and in JS, is through the construction of prototypes, the prototype is related to the following several terms:

① constructor: There is a prototype property inside the constructor that points to the prototype. In JS, constructors and functions belong to a conceptual category, both reference types, and can be instantiated as objects. The only difference is that the use of the new keyword to invoke the function can make this function a constructor, which is very well understood, because in the Class C language like Java, C # This constructor is the same as the method is the same name. If you are instantiating a class, use new to construct an instance of a class. Prototype holds a pointer to the prototype of the constructor . after inheritance is implemented, reference types (like Arrya, function, and so on) that are saved in the prototype are shared by all instantiated objects. Prototyping is an important way to implement inheritance in JS, and by constructing a prototype chain, you can implement code reuse, which is explained later in code.

② Prototype: Holds a constructor property inside the prototype, which holds a pointer to the constructor.

③ Object (instance): holds a [[prototype]] pointer inside the instance, pointing to the prototype, where all the properties and methods in the prototype can be accessed by all instances through this [[prototype]].

In inheritance it is important to note that the properties of the underlying type stored in the prototype can be overridden after inheritance (due to the JS dynamic add attribute), this is not a problem (such as string, number, bool, etc.), the problem is on the reference type of the properties (and functions), if an array is defined in the prototype , then this attribute will be shared in all instances, and any changes made to this array in one instance will be reflected in the other instances, which undermines the encapsulation requirements in object-oriented program design. So, here's a look at the two best examples of what to do if you are going to be effective in building inheritance.

The first one:

1 functionBaseClass (name,age) {2      This. Name =name;3      This. Age =Age ;4 }5 6Baseclass.prototype = {7 Constructor:baseclass,8Sayname:function() {9Console.log ( This. Name);Ten     } One }; A functionDerivedClass (name,age,job) { -      This. Job =job; -Baseclass.call ( This, name,age,job); the } -  -Derivedclass.prototype =NewBaseClass (); -Derivedclass.prototype.sayhi=function() { +Console.log ( This. Job); - } + varDerived1 =NewDerivedClass ("Bob", +, "software Engineer"); AConsole.log (Derived1.name);//Pang atDerived1.sayname ();//Pang -Derived1.sayhi ();//Software Engineer - varDerived2 =NewDerivedClass ("Loryn", +, "Doctor"); -Console.log (Derived2.name);//Loryn -Derived2.sayname ();//Lory -Derived2.sayhi ();//Doctor

This is one of the industry's most recommended implementations of inheritance, in this case baseclass is treated as a base class, and DerivedClass is considered a subclass. As you can see, one of the important ways to implement inheritance in JS is by constructing a prototype chain:

Derivedclass.prototype = new baseclass (); The prototype attribute of the DerivedClass constructor is pointed to BaseClass. This code is normal to run, and there are still no bugs to see. Let's change this code snippet:
functionBaseClass (name,age) { This. Name =name;  This. Age =Age ;} Baseclass.prototype={constructor:baseclass, favoritecolor:["Red", "green"),//newly added propertiesSayname:function() {Console.log ( This. Name); }};functionDerivedClass (name,age,job) { This. Job =job; Baseclass.call ( This, name,age,job);} Derivedclass.prototype=NewBaseClass ();D erivedClass.prototype.sayHi=function() {Console.log ( This. Job);}

var derived1 = new DerivedClass ("Bob", +, "software Engineer");
Derived1.favoriteColor.push ("Black");
Console.log (Derived1.favoritecolor),//["Red", "green", "BLACJK"]
var derived2 = new DerivedClass ("Loryn", +, "Doctor");
Console.log (Derived2.favoritecolor),//["Red", "green", "BLACJK"] weird place here

This above code is based on the addition of a property named FavoriteColor to BaseClass's prototype, which is an array, a reference type, now, or a definition of two derivedclass, Add a "black" element like one of the DerivedClass FavoriteColor, however, this element can also be shared in the derived2 after the instantiation. The present is a disadvantage of this popular way of inheriting JS. So, when inheriting in this way, pay attention to the following: In the process of inheritance, we should pay attention to the "function" of the prototype and the constructor function. In the prototype, only the function is stored, because the function itself is an object, because of the flexibility of the This keyword in JS, in the JS prototype to store functions can be used to maximize the reuse of functions. Put the attribute in the constructor, however this is not an egg for the value of the reference type, because Derivedclass.prototype = new BaseClass (); This sentence assigns the prototype of the subclass to a constructor of the base class, So in the prototype of the subclass, all the properties in the constructor for the base class are also stored, including the properties of the reference type. So, with this inheritance, the fundamental solution is to not declare properties of the reference type in the base class. One drawback of this inheritance is that the constructor is used in multiple places: the first time is in derivedclass.prototype = new BaseClass (), and the second time in Baseclass.call (This,name,age,job); There are also some problems in performance.

The second approach is described below:

First define two functions:

function Object (o) {    function  F () {    }    = o.prototype;     return New F ();} function Inheritprototype (subtype, supertype) {    var prototype = object (supertype.prototype);     = subtype;     = prototype;}

A function is an object (), which takes a prototype of a constructor, defines a constructor inside an object, and assigns the incoming prototype to the prototype of this well-defined constructor.

Another function is inheritprototype, which literally means inheriting the prototype. This function takes two constructors as arguments, inside the function, uses the object () function to return an instantiated constructor, and then treats the constructor as a prototype. A constructor property is added for this constructor (constructor is a property in the prototype, because the object function returns a constructor and does not constructor this property, so set one manually), and manually set the value of the constructor property to the first parameter passed in (you can see that the first parameter passed in is as a subclass and the other is a base class). The prototype of the first parameter is then set to this constructor. This function basically solves the first kinds of bad situations that are encountered above:

"Use Strict";functionObject (o) {functionF () {} F.prototype=o; return NewF ();}functionInheritprototype (subtype, supertype) {varPrototype =object (Supertype.prototype); Prototype.constructor=subtype; Subtype.prototype=prototype;}functionBaseClass (name, age) { This. Name =name;  This. Age =Age ;  This. FavoriteColor = ["Red", "green"];//newly added properties}baseclass.prototype.sayname=function() {Console.log ( This. name);};functionDerivedClass (name, age, job) { This. Job =job; Baseclass.call ( This, name, age);} Inheritprototype (DerivedClass, baseclass);//replace Derivedclass.prototype=new baseclass ();DerivedClass.prototype.sayHi =function() {Console.log ( This. Job);}varDerived1 =NewDerivedClass ("Bob", +, "software Engineer");d Erived1.favoriteColor.push ("Black"); Console.log (Derived1.favoritecolor);//["Red", "green", "BLACJK"]Derived1.sayname ();//BobvarDerived2 =NewDerivedClass ("Loryn", +, "Doctor"); Console.log (Derived2.favoritecolor);//["Red", "green"]

The first thing to solve is the number of times the constructor is used, and this optimization uses only one constructor:

Baseclass.call (this, name, age);
Then the problem with the prototype chain is solved:
Inheritprototype (DerivedClass, BaseClass);//Replace Derivedclass.prototype=new baseclass ();
Calling the object function in the Inheritprototype function, the object function assigns the incoming prototype directly to the prototype of the newly created constructor. In the Inheritprototype function, the inheritance relationship between the two constructors is completed.

How inheritance is implemented in JavaScript

Related Article

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.