当前位置:网站首页>Es5 thinking of writing inheritance
Es5 thinking of writing inheritance
2022-07-25 15:09:00 【Henry_ Nan】
stay js in , There are several methods of inheritance :
Constructor inheritance
function Parent() {
this.name = 'parent';
}
function Child(age) {
Parent.call(this);
this.age = age;
}
var c = new Child(12);
console.log(c.name); // Output parent
The principle is Child Use in constructor call Changed the this Point to , bring Child The object has been increased name attribute , The value is ’parent’, Completed inheritance .
The disadvantage of this method is : Things on the prototype chain of parent functions cannot be inherited
function Parent() {
this.name = 'parent';
}
Parent.prototype.say = function () {
console.log('say');
};
function Child(age) {
Parent.call(this);
this.age = age;
}
var p = new Parent(); //new One Parent Object for comparison
p.say(); // Output say
var c = new Child(12);
c.say(); //undifined
say yes Parent The method on the prototype chain ,Parent When an object calls a method , If you don't exist, go back to the prototype chain to find , Found on the prototype chain say Method , and Child Object does not inherit Parent Prototype chain of objects , So when it looks up, it can't find , Output undifined.
Prototype chain inheritance
function Parent() {
this.name = 'parent';
}
Parent.prototype.say = function () {
console.log('say');
};
function Child(age) {
this.age = age;
}
Child.prototype = new Parent();
var c = new Child(12);
console.log(c.name); // Output parent
c.say() // Output say
Prototype chain inheritance is to directly let Child Constructor's prototype Direct to Parent object , such Parent Things that are Child Object can be found directly from its prototype chain .
The disadvantage of this method is : When creating multiple instances , If different instances may affect each other , for example :
function Parent() {
this.name = 'parent';
this.arr = [1,2,3,4]
}
Parent.prototype.say = function () {
console.log('say');
};
function Child(age) {
this.age = age;
}
Child.prototype = new Parent();
var c1 = new Child(12);
var c2 = new Child(12);
console.log(c1.arr); //[1,2,3,4]
console.log(c2.arr); //[1,2,3,4]
c1.arr.push(5);
console.log(c1.arr); //[1,2,3,4,5]
console.log(c2.arr); //[1,2,3,4,5]
Here only for c1 Of arr It's changed , But it affected c2 Of arr, The reason is this way of inheritance , The prototype of the instance is the same object , namely new Parent() Coming out Parent example , When instance search arr If you can't find it here, you will find it on the prototype chain Parent Properties of , eureka arr, and arr It is also a reference type , therefore c1 modify arr when ,c2 Of arr It will change .
Constructor and prototype chain inheritance combination method
function Parent() {
this.name = 'parent';
this.arr = [1,2,3,4]
}
Parent.prototype.say = function () {
console.log('say');
};
function Child(age) {
Parent.call(this);
this.age = age;
}
Child.prototype = new Parent();
var c1 = new Child(12);
var c2 = new Child(12);
console.log(c1.arr); //[1,2,3,4]
console.log(c2.arr);//[1,2,3,4]
c1.arr.push(5);
console.log(c1.arr); //[1,2,3,4,5]
console.log(c2.arr); //[1,2,3,4]
The difference between this combination and the previous method is , When the instance is created Parent In the properties of the , So I won't go Parent seek arr, Modified arr It is in their respective attributes arr, There will be no impact , At the same time, he inherited Parent Things on the prototype chain .
Here's an optimization :
Before Child.prototype = new Parent() That is, the second inheritance method above , To inherit Parent The prototype chain inherits at the same time Parent What's in the function , Now in Child Function has been used Parent.call(this) Directly inherited Parent What's in the function , Then the prototype chain that directly inherits the parent function is finished, that is :
function Parent() {
this.name = 'parent';
this.arr = [1,2,3,4];
}
Parent.prototype.say = function () {
console.log('say');
};
function Child(age) {
Parent.call(this);
this.age = age;
}
Child.prototype = Parent.prototype;
var c = new Child(12);
console.log(c.name); // Output parent
c.say(); // Output say
After optimization , There are still shortcomings :
console.log(c.constructor); // Output Parent() {this.name = 'parent';this.arr = [1,2,3,4];}
Find... Here Child The prototype of constructor What we found was Parent Of constructor, The reason is because Child.prototype = Parent.prototype It's going to be Parent Of prototype Directly assign to Child Of prototype, So it's constructor Must be Parent Of constructor, At this time, it cannot be modified directly :
Child.prototype = Parent.prototype;
Child.prototype.constructor = Child;
console.log(c.constructor); // Output function Child(age) {Parent.call(this);this.age = age;}
console.log(new Parent().constructor); // Output function Child(age) {Parent.call(this);this.age = age;}
This is because Parent.prototype( object ) Is a reference type , So modify Child Of constructor,Parent Of constructor It will change too. , So will Child.prototype = Parent.prototype; Revise it :
function Parent() {
this.name = 'parent';
this.arr = [1,2,3,4];
}
Parent.prototype.say = function () {
console.log('say');
};
function Child(age) {
Parent.call(this);
this.age = age;
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
var c = new Child(12);
console.log(c.name);
c.say();
console.log(c.constructor); // Output function Child(age) {Parent.call(this);this.age = age;}
console.log(new Parent().constructor); // Output Parent() {this.name = 'parent';this.arr = [1,2,3,4];}
use Object.create(Parent.prototype) This method creates a new object , Assign a value to Child.prototype, Such changes Child Of constructor when ,Parent Of constructor Will not be affected .
This is the most perfect way
ps:es5 And the following cannot be inherited perfectly array, Relevant contents can be searched by yourself
边栏推荐
- 45padding won't open the box
- 6月产品升级观察站
- Sublimetext-win10 cursor following problem
- Splice a field of the list set into a single string
- 打开虚拟机时出现VMware Workstation 未能启动 VMware Authorization Service
- LeetCode_字符串_中等_151.颠倒字符串中的单词
- 006 operator introduction
- 如何解决Visual Studio中scanf编译报错的问题
- dpdk 收发包问题案例:使用不匹配的收发包函数触发的不收包问题定位
- Leetcode-198- house raiding
猜你喜欢

ESXI6.7.0 升级到7.0U3f(2022年7月12 更新)

41 图片背景综合-五彩导航图

Award winning interaction | 7.19 database upgrade plan practical Summit: industry leaders gather, why do they come?

node学习

《三子棋》C语言数组应用 --n皇后问题雏形

Implement a simple restful API server

Raft of distributed consistency protocol

44 Sina navigation, Xiaomi sidebar exercise

"Ask every day" briefly talk about JMM / talk about your understanding of JMM

45padding won't open the box
随机推荐
How many ways can you assign initial values to a two-dimensional array?
Handle Oracle deadlock
Spark002---spark任务提交,传入json作为参数
[Nacos] what does nacosclient do during service registration
node学习
35 快速格式化代码
LeetCode第 303 场周赛
"Ask every day" how locksupport realizes thread waiting and wakeup
Scala110-combineByKey
Unable to start web server when Nacos starts
vscode 插件篇收集
Implementation of redis distributed lock
006 operator introduction
sql to linq 之存储过程偏
继承的实现过程及ES5和ES6实现的区别
Live classroom system 05 background management system
剑指Offer | 二进制中1的个数
转载----如何阅读代码?
Automatically set the template for VS2010 and add header comments
Client error: invalid param endpoint is blank