今天又是忙碌的一天,就不写长篇大论了,继续分享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代码的时候,使用的就是寄生组合继承