JS几种继承方法介绍

36 阅读2分钟
1.原型继承

就是你的原型赋值给我的原型 Cat.prototype = Animal.prototype 继承后可以通过.prototype对原型进行修改,这就会导致影响其他继承该原型的对象的属性,这也是原型继承的缺点

// 抽象:所有动物都会吃
 function Animal() {}
 Animal.prototype.desc = '这是一种动物'
 Animal.prototype.eat = function(){
     console.log('哇呜,吃..',this.name,this.desc);
 }

 function Cat(name){
     this.name = name;
 }
 // 原型继承:你的原型赋值给我的原型
 Cat.prototype = Animal.prototype;

 new Cat('小猫').eat();
 // 对原型进行修改
 Cat.prototype.desc = 'desc变成了一只小狗';
 Cat.prototype.eat = function(){
     console.log('狗的原型受到了影响!');
 }

 function Dog(name){
     this.name = name;
 }
 // 原型继承:你的原型赋值给我的原型
 Dog.prototype = Animal.prototype;        
 new Dog('小狗').eat();
2. 构造函数继承

思想是利用父类构造函数实现数据共享,缺点也是子类可以随意修改父类的数据

// 父类
function Animal(name) {
    this.name = name;
    this.eat = function () {
        console.log(this.name, '吃吃吃,就知道吃')
    }
}

// 子类调用父类构造函数
function Cat(name) {
    Animal.call(cat, name); //调用时临时指定Animal this指向为传入的cat
}

new Cat('Green').eat();
3. 组合继承(原型继承+构造函数继承)

组合继承 = this绑定父类构造函数 + 将原型=父类原型

function Animal(name) {
    this.name = name;
}
Animal.prototype.eat = function () {
    console.log('哇呜,吃..', this.name);
}

// 组合继承
function Cat(name) {
    Animal.call(this, name);
}
Cat.prototype = Animal.prototype;

new Cat('XXX').eat();
4. 派生继承

1)用Object.create()继承时创建新的对象,解决了公共原型被修改影响所有实例的问题; 2).prototype.constructor = XX 将原型构造函数指向自己的构造函数,掰回歪曲的构造函数; 3)通过.prototype[Symbol.toStringTag]来修改子类原型的[类型描述]以及父类原型的[类型描述];

function Animal(name) {
    this.name = name;
}
Animal.prototype.eat = function () {
    console.log('哇呜,吃..', this.name);
}
// 【重点3】修改原型的[类型描述]
Animal.prototype[Symbol.toStringTag] = Animal.name;

// 组合继承
function Cat(name) {
    Animal.call(this, name);
}
// 【重点1 派生】:解决公共原型被修改影响所有实例的问题
Cat.prototype = Object.create(Animal.prototype);
// 【重点2】掰回歪曲的构造函数
Cat.prototype.constructor = Cat;
// 【重点3】修改原型的[类型描述]
Cat.prototype[Symbol.toStringTag] = Cat.name;

// 测试
var dogPrototype = Object.create(Animal.prototype);
console.log(Cat.prototype === dogPrototype); // false

var c1 = new Cat('XXX');
console.log('小猫:', c1);
c1.eat();