search
HomeWeb Front-endJS TutorialSix ways to implement inheritance in JavaScript

Six ways to implement inheritance in JavaScript

Oct 23, 2017 am 09:44 AM
javascriptjsWay

Description of inheritance in javascript:

Many object-oriented languages ​​support two inheritance methods: interface inheritance and implementation inheritance. Interface inheritance only inherits method signatures, while implementation inheritance inherits the actual methods. In JavaScript, interface inheritance cannot be implemented because the function has no signature, but only implementation inheritance is supported, and implementation inheritance is mainly achieved through the prototype chain.

                                                                                                                                                                                                                           First of all, quote the official document’s description of the prototype chain: The basic idea is to use prototypes to let one reference type inherit the properties and methods of another reference type. To understand this concept, you must first clarify the relationship between constructors, prototypes, and instances: each constructor (as long as it is a function) has a prototype attribute, which points to an object (this object is the prototype object of the constructor); the prototype object (As long as it is an object), there is a constructor attribute, which points to a constructor; and the instance contains an internal pointer [[Prototype]] pointing to the prototype object. To put it bluntly, the construction of the prototype chain is achieved by assigning an instance of one type to the prototype of another constructor. This way the subtype can access all properties and methods defined on the supertype. Each object has its own prototype object, which uses the prototype object as a template to inherit properties and methods from the prototype object. The prototype object can also have its own prototype and inherit properties and methods from it, layer by layer, and so on. The relationship is called a prototype chain and explains why one object has properties and methods defined on other objects.


Six ways to implement inheritance in javascript:

1. Prototype chain

2. Borrowed constructor

# 3. Combined inheritance (use prototype chain and borrowed constructor in combination )

4, prototype inheritance

# 5, parasitic inheritance


      6. Parasitic combined inheritance (use combined inheritance and parasitic inheritance)

1. Prototype chain

// 实现原型链的一种基本模式
function SuperType(){
            this.property = true;
}
SuperType.prototype.getSuperValue = function(){
            return this.property;
};
function SubType(){
            this.subproperty = false;
}

// 继承,用 SuperType 类型的一个实例来重写 SubType 类型的原型对象
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
            return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue());     // true

PS: SubType inherits SuperType, and inheritance is achieved by creating an instance of SuperType and assigning the instance to the prototype of SubType. The essence of the implementation is to override the prototype object of the subtype and replace it with an instance of the new type. The new prototype object of the subtype has an internal property [[Prototype]] that points to the SuperType prototype, and a property constructor inherited from the SuperType prototype that points to the SuperType constructor. The final prototype chain is like this: instance points to the prototype of SubType, the prototype of SubType points to the prototype of SuperType, and the prototype of SuperType points to the prototype of Object (the default prototype of all functions is an instance of Object, so the default prototype will contain an internal Pointer to Object.prototype).
Disadvantages of the prototype chain:
1. When inheritance is implemented through a prototype, the prototype will actually become an instance of another type. As a result, the original instance attributes naturally become the current prototype attributes, and will be shared by all instances. Understand this way: the instance properties of the reference type value defined in the supertype constructor will become prototype properties on the subtype prototype and be shared by all subtype instances.
          2. When creating an instance of a subtype, parameters cannot be passed to the constructor of the supertype.

2. Borrowing constructors (also called fake objects or classic inheritance)

// 在子类型构造函数的内部调用超类型构造函数;使用 apply() 或 call() 方法将父对象的构造函数绑定在子对象上
function SuperType(){
            // 定义引用类型值属性
            this.colors = ["red","green","blue"];
}
function SubType(){
            // 继承 SuperType,在这里还可以给超类型构造函数传参
            SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push("purple");
alert(instance1.colors);     // "red,green,blue,purple"

var instance2 = new SubType();
alert(instance2.colors);     // "red,green,blue"

PS: By using the apply() or call() method, we are actually creating The SuperType constructor is called in the context of a SubType instance. This causes all object initialization code defined in the SuperType() function to be executed on the new SubType object. As a result, each instance of SubType will have its own copy of the colors property.
The advantage of borrowing a constructor is that it solves two problems with prototype chain implementation inheritance; the disadvantage of borrowing a constructor is that the methods are all defined in the constructor, so function reuse cannot be achieved. Moreover, methods defined in the supertype's prototype are not visible to subtypes, so all types can only use the constructor pattern.

3. Combination inheritance (also called pseudo-classical inheritance)

// 将原型链和借用构造函数的技术组合到一块。使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。
这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有自己的属性。
function SuperType(name){
            this.name = name;
            this.colors = ["red","green","blue"];
}
SuperType.prototype.sayName = function(){
            alert(this.name);
};
function SubType(name,age){
            // 借用构造函数方式继承属性
            SuperType.call(this,name);
            this.age = age;
}
// 原型链方式继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
            alert(this.age);
};
var instance1 = new SubType("luochen",22);
instance1.colors.push("purple");
alert(instance1.colors);      // "red,green,blue,purple"
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType("tom",34);
alert(instance2.colors);      // "red,green,blue"
instance2.sayName();
instance2.sayAge();

PS: Combination inheritance avoids the defects of prototype chain and borrowed constructor, integrates their advantages, and becomes the most commonly used in JavaScript inheritance model. Furthermore, using the instanceof operator and the isPrototype() method can also be used to identify objects created based on compositional inheritance. However, it also has its own shortcomings. The biggest problem is that no matter what the circumstances, the supertype constructor is called twice: once when creating the subtype prototype, and once inside the subtype constructor.

4. Prototypal inheritance

// 借助原型可以基于已有的对象创建新对象,同时还不必因此创建自定义类型。
1、自定义一个函数来实现原型式继承
function object(o){
            function F(){}
            F.prototype = o;
            return new F();
}

PS: Inside the object() function, first create a temporary constructor, and then use the incoming object as the constructor prototype, and finally returns a new instance of this temporary type. Essentially, object() performs a shallow copy of the object passed into it.
2. Use the Object.create() method to implement prototypal inheritance. This method accepts two parameters: an object to be used as the prototype of the new object and an object to define additional properties for the new object. This method works the same as the object() method when one parameter is passed in.
When the second parameter is passed in, any properties specified will override the properties of the same name on the prototype object.

var person = {
            name: "luochen",
            colors: ["red","green","blue"]
}; 
var anotherPerson1 = Object.create(person,{
            name: {
                    value: "tom"
            }
});
var anotherPerson2 = Object.create(person,{
            name: {
                    value: "jerry"
            }
});
anotherPerson1.colors.push("purple");
alert(anotherPerson1.name);     // "tom"
alert(anotherPerson2.name);     // "jerry"
alert(anotherPerson1.colors);    // "red,green,blue,purple"
alert(anotherPerson2.colors);    // "red,green,bule,purple";

PS: If you just want one object to be similar to another object, prototypal inheritance is fully capable. But the disadvantage is: properties containing reference type values ​​always share the corresponding value.

5. Parasitic inheritance

// 创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回这个对象
function createPerson(original){
            var clone = Object.create(original);   // 通过 Object.create() 函数创建一个新对象
            clone.sayGood = function(){              // 增强这个对象
                        alert("hello world!!!");
            };
            return clone;                                      // 返回这个对象 
}

PS: Parasitic inheritance is also a useful pattern when the main consideration is objects rather than custom types and constructors. The disadvantage of this mode is that it cannot reuse functions.

6. Parasitic combined inheritance

// 通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型
function SuperType(name){
            this.name = name;
            this.colors = ["red","green","blue"];
}
SuperType.prototype.sayName = function(){
            alert(this.name);
};
function SubType(name,age){
            SuperType.call(this,name);
            this.age = age;
}
// 创建超类型原型的一个副本
var anotherPrototype = Object.create(SuperType.prototype);
// 重设因重写原型而失去的默认的 constructor 属性
anotherPrototype.constructor = SubType;
// 将新创建的对象赋值给子类型的原型
SubType.prototype = anotherPrototype;

SubType.prototype.sayAge = function(){
            alert(this.age);
};
var instance1 = new SubType("luochen",22);
instance1.colors.push("purple");
alert(instance1.colors);      // "red,green,blue,purple"
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType("tom",34);
alert(instance2.colors);      // "red,green,blue"
instance2.sayName();
instance2.sayAge();

PS: The high efficiency of this example is reflected in the fact that it only calls the SuperType constructor once, and thus avoids creating unnecessary objects on SubType.prototype. Required, redundant attributes. At the same time, the prototype chain remains unchanged; therefore, the instance operator and isPrototype() method can be used normally.

The above is the detailed content of Six ways to implement inheritance in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Statement
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
JavaScript and the Web: Core Functionality and Use CasesJavaScript and the Web: Core Functionality and Use CasesApr 18, 2025 am 12:19 AM

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding the JavaScript Engine: Implementation DetailsUnderstanding the JavaScript Engine: Implementation DetailsApr 17, 2025 am 12:05 AM

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

From C/C   to JavaScript: How It All WorksFrom C/C to JavaScript: How It All WorksApr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Have Crossplay?
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor