Appearance
实现继承的7种方式
JS是一门弱类型动态语言,封装和继承是他的两大特性
原型链继承
将父类的实例作为子类的原型
定义父类
javascript
// 定义一个动物类
function Animal(name){
// 属性
this.name = name || 'Animal'
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!')
}
}
// 原型方法
Animal.prototype.eat = function(food){
console.log(this.name + '正在吃:' + food)
}子类:
javascript
function Cat(){}
Cat.prototype = new Animal()
Cat.prototype.name = 'cat'
//TestCode
var cat = new Cat()
console.log(cat.name) // cat
console.log(cat.eat('fish')) // cat正在吃:fish
console.log(cat.sleep()) // cat正在睡觉!
console.log(cat instanceof Animal) // true
console.log(cat instanceof Cat) // true优缺点:简单易于实现,但是要想为子类新增属性和方法,必须要在new Animal()这样的语句后执行,无法实现多继承
构造继承
实质是利用call来改变Cat中的this指向
javascript
function Cat(name){
Animal.call(this)
this.name = name || 'Tom'
}优缺点:可以实现多继承,不能继承原型属性/方法
实例继承
为父类添加新特性,作为子类实例返回
javascript
function Cat(name){
var instance = new Animal()
instance.name = name || 'Tom'
return instance
}优缺点:不限制调用方式,但不能实现多继承
拷贝继承
将父类的属性和方法拷贝一份到子类中
javascript
function Cat(name){
var animal = new Animal()
for(var p in animal){
Cat.prototype[p] = animal[p]
}
Cat.prototype.name = name || 'Tom'
}优缺点:支持多继承,但是效率低占用内存
组合继承
通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
javascript
function Cat(name){
Animal.call(this)
this.name = name || 'Tom'
}
Cat.prototype = new Animal()
Cat.protptype.constructor = Cat寄生组合继承
javascript
function Cat(name){
Animal.call(this)
this.name = name || 'Tom'
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){}
Super.prototype = Animal.prototype
// 将实例作为子类的原型
Cat.prototype = new Super()
})()ES6的extends继承
ES6 的继承机制是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this
javascript
// 父类
class Person{
// constructor是构造方法
constructor(skin,language){
this.skin = skin
this.language = language
}
say(){
console.log('我是父类')
}
}
// 子类
class Chinese extends Person{
constructor(skin,language,position){
//console.log(this);//报错
super(skin, language);
//super();相当于父类的构造函数
//console.log(this);调用super后得到了this,不报错,this指向子类,相当于调用了父类.prototype.constructor.call(this)
this.positon = positon;
}
aboutMe() {
console.log(`${this.skin} ${this.language} ${this.positon}`);
}
}
//调用只能通过new的方法得到实例,再调用里面的方法
let obj = new Chinese('红色', '中文', '香港');
obj.aboutMe();
obj.say();