跳到主要内容

八种继承方式

原型链继承

子对象可以访问父对象原型链上的属性和方法,

对原型修改影响所有子对象

function Parent (){
this.name = 'Parent';
}
Parent.prototype.sayHello = function(){
console.log('hello')
}
function Child () {
this.name = 'Child';
}
Child.prototype = new Parent();
let child = new Child();
child.sayHello();

构造函数继承

在子构造函数中调用父构造函数来实现,只能继承父构造函数的实例属性

无法访问父对象原型链上的属性和方法

function Parent (name){
this.name = name;
}
function Child (name) {
Parent.call(this,name)
}
let child = new Child('Child');

组合继承

继承了父构造函数的属性,又继承了父构造函数原型对象上的方法。

会调用两次父构造函数

function Parent (name){
this.name = name;
}
Parent.prototype.sayHello = function(){
console.log('hello')
}
function Child (name) {
Parent.call(this,name)
}
Child.prototype = new Parent('parent');
let child = new Child('Child');
child.sayHello();
console.log(child.name)

原型式继承

创建一个新对象,将其原型对象指向另一个已有的对象

可以实现属性和方法的继承,但是不能传递构造函数的参数

var Parent ={
name:'Parent',
sayHello: function() {
console.log('Hello')
}
}
var child = Object.create(parent);
console.log(child.name)
child.sayHello();

寄生式继承

在原型式继承的基础上,增强对象的功能。

难以重用

function createAnother(obj) {
// 创建一个新对象
let clone = Object.create(obj);
// 增强对象的功能
clone.sayHi = function() {
console.log('Hi');
};
// 返回增强后的对象
return clone;
}

let person = {
name: 'John',
age: 30
};

let anotherPerson = createAnother(person);

console.log(anotherPerson.name);
anotherPerson.sayHi();

寄生组合式继承

只调用一次父类构造函数

// 通用版
function Parent(name) {
this.name = name;
}
Parent.prototype.getName = function() {
console.log(this.name);
};
function Child(name, age) {
// 调用父类的构造函数
Parent.call(this, name);
this.age = age;
}
function createObj(o) {
// 目的是为了继承父类原型上的属性和方法,在不需要实例化父类构造函数的情况下,避免生成父类的实例,如new Parent()
function F() {}
F.prototype = o;
// 创建一个空对象,该对象原型指向父类的原型对象
return new F();
}

// 等同于 Child.prototype = Object.create(Parent.prototype)
Child.prototype = createObj(Parent.prototype);
Child.prototype.constructor = Child;

let child = new Child("tom", 12);
child.getName(); // tom

class

class Parent {
constructor(age) {
this.age = age;
}
getName() {
console.log(this.name);
}
}
class Child extends Parent {
constructor(name, age) {
super(age);
this.name = name;
}
}

mixin继承

将多个对象的方法合并到一个对象中,然后将这个对象混入到其他对象中,从而实现继承和代码复用

手写class类

function selfClass(Child, Parent) {
// Object.create 第二个参数,给生成的对象定义属性和属性描述符/访问器描述符
Child.prototype = Object.create(Parent.prototype, {
// 子类继承父类原型上的属性和方法
constructor: {
enumerable: false,
configurable: false,
writable: true,
value: Child
}
});
// 继承父类的静态属性和静态方法
Object.setPrototypeOf(Child, Parent);
}

// 测试
function Child() {
this.name = 123;
}
function Parent() {}
// 设置父类的静态方法getInfo
Parent.getInfo = function() {
console.log("info");
};
Parent.prototype.getName = function() {
console.log(this.name);
};
selfClass(Child, Parent);
Child.getInfo(); // info
let tom = new Child();
tom.getName(); // 123