首先 这是一个父类
// 父类
function Animal(name){
this.name = name
this.eat = function() {
console.log(`${this.name} is eating`)
}
}
Animal.prototype = {
constructor: Animal,
sayName() {
console.log(`my name is ${this.name}`);
}
}
继承的方式有以下几种,下面我们详细介绍这几种继承方式
- 构造函数继承
- 原型链继承
- 组合继承
- 原型式继承
- 寄生式继承
- 寄生组合式继承
1. 构造函数继承
构造函数(只能继承属性,不能继承原型prototype上的方法, Cat上没有sayName的方法)
function Cat(name, age) {
Animal.call(this, name)
this.age = age
}
Cat.prototype = {
sheep() {
console.log(`${this.name} is sheeping`);
}
}
var cat = new Cat('cat', 12)
console.log(Cat.prototype.constructor === Cat) // false
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
// 总结:
// 1. 实例只是子类Cat的不是父类Animal的实例
// 2. 子类Cat不能继承父类Animal的prototype上的属性
// 3. 子类Cat可以继承多个父类
// 4. 继承多个父类的所有属性
2. 原型链继承
function Cat() {}
Cat.prototype = new Animal('cat')
console.log(Cat.prototype.constructor === Cat) // false, 所以上面应该重新赋值
console.log(a instanceof Animal) // true
console.log(a instanceof Cat) // true
总结
- 实例是子类Cat也是父类Animal的实例
- 构造器Cat是完全继承的Animal,没有自己的属性和方法
- 构造的实例无法向构造器传参
- 让Cat原型等于父类的实例。
3. 实例继承
function Cat(name, age) {
var instance = new Animal(name)
instance.age = age
return instance;
}
Cat.prototype = {
constructor: Animal,
sheep() {
console.log(`${this.name} is sheeping`);
}
}
var cat = new Cat('cat', 12)
console.log(Cat.prototype.constructor === Cat) // true
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false
总结
- 实例只是父类的实例不是子类的实例
- 可以添加属性和方法
4. 拷贝继承
function Cat(name, age) {
var instance = new Animal(name)
for(let o in instance) {
Cat.prototype[o] = instance[o]
}
Cat.prototype.name = name
Cat.prototype.age = age
}
console.log(a instanceof Cat) // false
console.log(a instanceof Animal) // true
总结
- 实例只是父类的实例不是子类的实例
- 可以添加属性和方法
- 无法拷贝不可枚举的属性
- for循环效率低
5. 对象冒充
6. 组合继承
function Cat(name, age){
Animal.call(this, name);
this.age = age
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat; // 需要修改
console.log(a instanceof Cat) // true
console.log(a instanceof Animal) // false
7. 寄生组合继承
function Cat(name, age){
Animal.call(this, name);
this.age = age
}
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
Cat.prototype.constructor = Cat; // 需要修复下构造函数
console.log(a instanceof Cat) // true
console.log(a instanceof Animal) // true
function content(obj) {
function F() {}
F.prototype = obj
return new F()
}
const sup = new Animal()
function subobject(obj) {
var sub = content(obj)
sub.name = 'gar'
return sub
}
const sup2 = subobject(sup)
console.log(sup2)
sup2.eat()
sup2.sayName()
8.原型式继承
function content2(obj) {
function F() {}
F.prototype = obj
return new F()
}
const sup3 = new Animal()
const sup4 = content2(sup3)
console.log(sup4.name, 1, sup4 instanceof Animal)
sup4.eat()
sup4.sayName()
9.构造函数继承+寄生继承
function Pig(name) {
Animal.call(this, name)
}
function content3(obj) {
function F() {}
F.prototype = obj;
return new F()
}
const sup6 = content3(Animal.prototype)
Pig.prototype = sup6;
sup6.constructor = Pig;
const sup5 = new Pig('111')
console.log(sup5)
sup5.eat()
sup5.sayName()