JS实现继承的6种方式
今天又是忙碌的一天,就不写长篇大论了,继续分享javascript基础知识,本篇是关于继承的,面试八股文,希望大家可以拿到自己满意的offer。
实现继承的6种方式
原型链
原型链继承
function Parent() {
this.name = 'parent';
this.arr = [1, 2, 3];
}
Parent.prototype.getName = function() {
return this.name;
}
function Child() {
}
Child.prototype = new Parent();
const child1 = new Child();
const child2 = new Child();
child1.arr.push(999);
console.log('child1', child1);
console.log('child2', child2);
缺点:
- 原型上的变量被所有实例共享,当一个实例改变引用类型里面的值时会影响其他实例
- 不能向父类构造函数传参
构造函数继承
优化了原型链继承共享原型变量的问题,也可以向父类构造函数传参
function Parent() {
this.name = 'parent';
this.arr = [1, 2, 3];
}
Parent.prototype.getName = function() {
return this.name;
}
function Child() {
Parent.call(this); //* 调用父类的构造器
}
const child1 = new Child();
const child2 = new Child();
child1.arr.push(999);
console.log('child1', child1);
console.log('child2', child2)
缺点:
- 无法复用父类的方法
组合继承
把原型链继承和构造器继承结合起来
function Parent() {
console.log('call Parent');
this.name = 'parent';
this.arr = [1, 2, 3];
}
Parent.prototype.getName = function() {
return this.name;
}
function Child() {
Parent.call(this); //* 1
}
Child.prototype = new Parent(); //* 2
const child1 = new Child();
const child2 = new Child();
child1.arr.push(999);
console.log('child1', child1);
console.log('child2', child2);
缺点:
- 多调用了一次构造函数
原型继承
以上是基于函数的继承,现在基于现有的对象继承
let parent = {
name: 'parent'
}
// 通过Object.create()
let child = Object.create(parent);
// 或者通过下面的方法create也是一样
function create(parent) {
function F() {};
F.prototype = parent;
return new F();
}
console.log(child);
缺点:
- 也是共享了父类的变量
寄生式继承
在原型继承的基础上增强
let parent = {
name: 'parent'
}
// 通过Object.create()
function extend(parent) {
let child = Object.create(parent);
child.getName = function() { // *只是上面的增强
return this.name;
}
return child;
}
console.log(child);
寄生组合式继承
优化了组合继承需要多调一次构造方法的缺点
同时也不会共享父类的变量
也能做到函数的复用
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function() {
return this.name;
}
function Child() {
Parent.call(this);
this.age = 18;
}
function extend(Child, Parent) {
Child.prototype = Object.create(Parent.prototype);
Child.prototype.contructor = Child;
}
extend(Child, Parent);
const obj = new Child();
babel将ES6的extend转换成ES5代码的时候,使用的就是寄生组合继承
转载自:https://juejin.cn/post/7135825328773005325