search
HomeWeb Front-endJS TutorialSummary of 9 inheritance implementation methods in JavaScript_javascript skills

Unlike class-based programming languages ​​such as C and Java, inheritance in JavaScript is prototype-based. At the same time, because JavaScript is a very flexible language, there are many ways to implement inheritance.

The first basic concept is about constructors and prototype chains. The constructor of the parent object is called Parent, the constructor of the child object is called Child, and the corresponding parent and child objects are parent and child respectively.

There is a hidden attribute [[prototype]] (note not prototype) in the object. In Chrome it is __proto__, but in some environments it is inaccessible. It points to the prototype of this object. When accessing the properties or methods of any object, all properties of the object will be searched first. If not found, the properties on the prototype object will be searched step by step along the prototype chain according to [[prototype]] until found. Otherwise return undefined.

1. Prototype chain inheritance:

The prototype chain is the default way to implement inheritance in JavaScript. If you want a child object to inherit the parent object, the simplest way is to point the prototype attribute of the child object's constructor to an instance of the parent object:

Copy code The code is as follows:

function Parent() {}
function Child() {}
Child.prototype = new Parent()

At this time, Child's prototype attribute has been rewritten and points to a new object, but the constructor attribute of this new object does not correctly point to Child. The JS engine will not automatically complete this work for us, which requires us to manually The constructor property of Child's prototype object repoints to Child:
Copy code The code is as follows:

Child.prototype.constructor = Child

The above is the default inheritance mechanism in JavaScript, which migrates the properties and methods that need to be reused to the prototype object, and sets the non-reusable parts as the object's own properties. However, this inheritance method requires a new instance as the prototype object, which is efficient. It will be lower.

2. Prototypal inheritance (non-prototype chain):

In order to avoid the problem of repeatedly creating prototype object instances in the previous method, you can directly point the prototype of the child object constructor to the prototype of the parent object constructor. In this way, all properties and methods in Parent.prototype can also be reused. At the same time, there is no need to repeatedly create prototype object instances:

Copy code The code is as follows:

Child.prototype = Parent.prototype
Child.prototype.constructor = Child

But we know that in JavaScript, objects exist as reference types. This method actually points the pointers saved in Child.prototype and Parent.prototype to the same object. Therefore, when we want to use the child object prototype If you extend some properties in order to continue inheritance later, the prototype of the parent object will also be rewritten, because there is always only one instance of the prototype object here, which is also the shortcoming of this inheritance method.

3. Temporary constructor inheritance:

In order to solve the above problem, you can use a temporary constructor to act as an intermediate layer. All operations on the child object prototype are completed on the instance of the temporary constructor and will not affect the parent object prototype:

Copy code The code is as follows:

var F = function() {}
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child

At the same time, in order to access the attributes in the parent class prototype in the child object, you can add an attribute pointing to the parent object prototype in the child object constructor, such as uber. In this way, the child object can be accessed directly through child.constructor.uber. to the parent prototype object.

We can encapsulate the above work into a function, and calling this function in the future can easily implement this inheritance method:

Copy code The code is as follows:

function extend(Child, Parent) {
var F = function() {}
F.prototype = Parent.prototype
Child.prototype = new F()
Child.prototype.constructor = Child
Child.uber = Parent.prototype
}

Then you can call it like this:
Copy code The code is as follows:

extend(Dog, Animal)

4. Attribute copy:

This inheritance method basically does not change the relationship of the prototype chain, but directly copies all the attributes in the parent prototype object to the child object prototype. Of course, the copy here only applies to basic data types, and object types only support Pass by reference.

Copy code The code is as follows:

function extend2(Child, Parent) {
var p = Parent.prototype
var c = Child.prototype
for (var i in p) {
         c[i] = p[i]
}
c.uber = p
}

This method reconstructs some prototype attributes, which will be less efficient when building objects, but can reduce the search of the prototype chain. However, I personally feel that the advantages of this method are not obvious.

5. Inheritance between objects:

In addition to the inheritance method between constructors, you can also directly inherit between objects without constructors. That is, copy object attributes directly, including shallow copy and deep copy.

Shallow copy:
Accept the object to be inherited, create a new empty object at the same time, copy the properties of the object to be inherited to the new object and return the new object:

Copy code The code is as follows:

function extendCopy(p) {
var c = {}
for (var i in p) {
         c[i] = p[i]
}
c.uber = p
Return c
}

After the copy is completed, the attributes that need to be rewritten in the new object can be manually rewritten.

Deep copy:
The problem of shallow copy is also obvious. It cannot copy the attributes of the object type but can only pass the reference. To solve this problem, deep copy must be used. The focus of deep copy lies in the recursive call of copy. When the properties of the object type are detected, the corresponding object or array is created and the basic type values ​​are copied one by one.

Copy code The code is as follows:

function deepCopy(p, c) {
c = c || {}
for (var i in p) {
If (p.hasOwnProperty(i)) {
If (typeof p[i] === 'object') {
                                   c[i] = Array.isArray(p[i]) ? [] : {}
                 deepCopy(p[i], c[i])
              } else {
c[i] = p[i]
            }
}
}
Return c
}

An ES5 Array.isArray() method is used to determine whether the parameter is an array. Environments that do not implement this method need to manually encapsulate a shim.
Copy code The code is as follows:

Array.isArray = function(p) {
Return p instanceof Array
}

However, array variables from different frameworks cannot be judged using the instanceof operator, but this situation is relatively rare.

6. Prototypal inheritance:

With the help of the parent object, create a new object prototyped by the parent object through the constructor:

Copy code The code is as follows:

function object(o) {
var n
Function F() {}
F.prototype = o
n = new F()
n.uber = o
Return n
}

Here, the parent object is directly set as the prototype of the child object. The Object.create() method in ES5 is this implementation.

7. Mixed use of prototypal inheritance and attribute copying:

In the prototypal inheritance method, the child object is constructed based on the passed in parent object. At the same time, in addition to the properties provided by the parent object, additional objects that need to be copied can be passed in:

Copy code The code is as follows:

function objectPlus(o, stuff) {
var n
Function F() {}
F.prototype = o
n = new F()
n.uber = o

for (var i in stuff) {
n[i] = stuff[i]
}
Return n
}


8. Multiple inheritance:

This method does not involve the operation of the prototype chain. Multiple objects whose attributes need to be copied are passed in, and all attributes are copied in sequence:

Copy code The code is as follows:

function multi() {
var n = {}, stuff, i = 0,
        len = arguments.length
for (i = 0; i         stuff = arguments[i]
for (var key in stuff) {
n[i] = stuff[i]
}
}
Return n
}

The objects are copied in order according to the order in which they are passed in. That is to say, if the object passed in later contains the same properties as the previous object, the latter will overwrite the former.

9. Constructor borrowing:

The call() and apply() methods in JavaScript are very easy to use, and their function of changing the method execution context can also play a role in the implementation of inheritance. The so-called constructor borrowing refers to borrowing the constructor of the parent object in the child object constructor to operate this:

Copy code The code is as follows:

function Parent() {}
Parent.prototype.name = 'parent'

function Child() {
Parent.apply(this, arguments)
}
var child = new Child()
console.log(child.name)


The biggest advantage of this method is that in the constructor of the sub-object, the sub-object's own properties are completely reconstructed, and the reference type variable will also generate a new value instead of a reference, so any operation on the sub-object Neither will affect the parent object.

The disadvantage of this method is that the new operator is not used during the construction process of the child object, so the child object will not inherit any attributes on the parent prototype object. In the above code, the name attribute of the child will be undefined.

To solve this problem, you can manually set the child object constructor prototype to an instance of the parent object again:

Copy code The code is as follows:

Child.prototype = new Parent()

But this will bring about another problem, that is, the constructor of the parent object will be called twice, once during the borrowing process of the parent object's constructor, and the other time during the inheritance prototype process.

To solve this problem, we need to remove a call to the parent object's constructor. Constructor borrowing cannot be omitted, so the last call can only be removed. Another way to implement prototype inheritance is to iteratively copy:

Copy code The code is as follows:

extend2(Child, Parent)

Just use the extend2() method implemented previously.
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
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

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)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

MantisBT

MantisBT

Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Powerful PHP integrated development environment