继承
原型链继承
子类的原型对象是父类的实例对象
优点:
- 简单易懂 缺点:
- 1 实例化子类时,没办法向父类的构造函数传值
- 2 所有子类实例共享一个父类,当某个子类修改了父类的属性时,其他子类也会受到影响
js
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Child() {
this.name = 'child';
}
Child.prototype = new Parent();
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Child() {
this.name = 'child';
}
Child.prototype = new Parent();
构造函数继承
在子类的构造函数中调用父类的构造函数
优点:
- 解决了原型链继承中,所有子类实例共有一个父类以及实例化子类时向父类传参的问题
缺点:
- 没办法继承父类原型上的属性和方法,父类的方法和属性会被重复创建
js
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Children () {
Parent.call(this);
}
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Children () {
Parent.call(this);
}
组合继承
子类构造函数调用了父类,子类的原型对象指向父类的实例对象
优点:
- 解决了构造函数继承无法继承父类原型上的属性和方法的问题
缺点:
- 实例化子类时,会重复调用父类的构造方法
js
function Parent () {
this.name = 'Parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Children () {
Parent.call(this);
}
Children.prototype = new Parent();
Children.prototype.constructor = Children;
function Parent () {
this.name = 'Parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Children () {
Parent.call(this);
}
Children.prototype = new Parent();
Children.prototype.constructor = Children;
寄生组合继承
优点:
- 解决了组合继承中,实例化子类时重复调用父类构造函数的问题
缺点:
- 相对复杂
js
function Parent () {
this.name = 'Parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Children () {
Parent.call(this);
}
Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
function Parent () {
this.name = 'Parent';
}
Parent.prototype.getName = function () {
return this.name;
}
function Children () {
Parent.call(this);
}
Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
Object.create 的实现原理如下:
js
const objectCreate = (parentPrototype) => {
const noop = function () {};
noop.prototype = parentPrototype;
return new noop();
}
const objectCreate = (parentPrototype) => {
const noop = function () {};
noop.prototype = parentPrototype;
return new noop();
}
extends 继承
优点:简洁美观
js
class Parent {
constructor () {
this.name = 'parent';
}
getName () {
return this.name;
}
}
class Children extends Parent {
constructor () {
super();
this.topic = 'children';
}
}
const children = new Children();
children.getName(); // parent
class Parent {
constructor () {
this.name = 'parent';
}
getName () {
return this.name;
}
}
class Children extends Parent {
constructor () {
super();
this.topic = 'children';
}
}
const children = new Children();
children.getName(); // parent