ES5
先看看ES5的组合继承
:
//定义 父构造函数Dog()
function Dog(name) {
this.name = name
}
//向Dog的原型对象添加eat方法
Dog.prototype.eat = function () {
console.log(this.name + '吃肉')
}
var lasi = new Dog('拉斯')
lasi.eat() //拉斯吃肉
//定义 子构造函数Husky(),实现继承
function Husky(name) {
// call() 改变this指向,这里从 指向Dog的实例 变为 指向Husky的实例
// 从而继承了父类的实例属性
Dog.call(this, name)
}
// 把 Dog实例 赋值 给 Husky原型对象,Husky.prototype就能找到eat()方法
//这就实现了方法的继承
Husky.prototype = new Dog()
// 再添加constructor属性
Husky.prototype.constructor = Husky
// 给Husky添加新方法
Husky.prototype.bark = function () {
console.log(this.name + ':呜呜呜呜~')
}
var ergou = new Husky('二狗')
ergou.eat() // 二狗吃肉
ergou.bark() // 二狗:呜呜呜呜~
组合继承
比较直观,且较好的实现的继承。但其缺点在于实现继承的过程中,调用了2次 Dog()。下面再介绍最佳方案——寄生式组合继承
。
function Dog(name) {
this.name = name
}
Dog.prototype.eat = function () {
console.log(this.name + " eat meat")
}
const lasi = new Dog('Lasi')
lasi.eat() // Lasi eat meat
function Husky(name) {
Dog.call(this, name)
}
// 盗取父类构造函数的原型(方式一)
function steal(obj) {
function F() { }
F.prototype = obj
return new F()
}
Husky.prototype = steal(Dog.prototype)
// 盗取父类构造函数的原型(方式二)
// Husky.prototype = Object.create(Dog.prototype)
// 添加constructor属性
Husky.prototype.constructor = Husky
Husky.prototype.bark = function () {
console.log(this.name + ": wu~~~~~")
}
const ergou = new Husky('Ergou')
ergou.eat() // Ergou eat meat
ergou.bark() // Ergou: wu~~~~~
es5实现继承的代码显得比较冗长和混乱,为此,ES6引入class
关键字。class是新的基础性语法糖结构,其背后本质上仍然是原型和构造函数的概念。
ES6
class Dog{
constructor(name){
this.name = name
}
eat(){
console.log(this.name + '吃肉')
}
}
class Husky extends Dog{
constructor(name){
super(name)
}
bark(){
console.log(this.name + ':呜呜呜')
}
}
var ergou = new Husky('二狗')
ergou.eat() // 二狗吃肉
ergou.bark() // 二狗:呜呜呜
ES6的继承确实很简洁!