继承内容:一共有三部分,一是实例属性/方法、二是原型属性/方法、三是静态属性/方法
ES5:
原型链继承、构造继承、组合继承、寄生继承, 最佳继承: 寄生组合式继承
父类的函数:
// 父类
function Parent(name) {
this.name = name// 实例属性
}
Parent.type = '午'// 静态属性
// 静态方法
Parent.sleep = function () {
console.log(`我在睡${this.type}觉`)
}
// 实例方法
Parent.prototype.say = function() {
console.log('我叫 ' + this.name)
}
继承实例属性/方法
要执行一下Parent函数才行,并且要修改它的this指向,这使用call、apply方法都行,属于构造函数继承
// 子类
function Son(name, age) {
// 继承父类的实例属性
Parent.call(this, name)
// 自己的实例属性
this.age = age
}
var s1 = new Son('小明', 23);
console.log(s1.name, s1.age); //小明 23
new 操作符的原理
继承原型属性/方法
关联Parent.prototype
1.使用Object.create
// Object.create
Son.prototype = Object.create(Parent.prototype);
Son.prototype.constructor = Son;
var s2 = new Son('小明1', 23);
console.log('s2', s2) // s2 Son {name: '小明1', age: 23}
s2.say() // 我叫 小明1
2.使用__proto__
Son.prototype.__proto__ = Parent.prototype
3.借用中间函数
function Fn() {}
Fn.prototype = Parent.prototype
Son.prototype = new Fn()
Son.prototype.constructor = Parent
继承静态属性/方法
也就是继承Parent函数本身的属性和方法,这个很简单,遍历一下父类自身的可枚举属性,然后添加到子类上即可:
Object.keys(Parent).forEach((prop) => {
Son[prop] = Parent[prop]
})
for (var prop in Parent) {
if (Parent.hasOwnProperty(prop)) {
Son[prop] = Parent[prop]
}
}
ES6:使用class继承
接下来我们使用ES6的class关键字来实现上面的例子:
// 父类
class Sup {
constructor(name) {
this.name = name
}
say() {
console.log('我叫 ' + this.name)
}
static sleep() {
console.log(`我在睡${this.type}觉`)
}
}
// static只能设置静态方法,不能设置静态属性,所以需要自行添加到Sup类上
Sup.type = '午'
// 另外,原型属性也不能在class里面设置,需要手动设置到prototype上,比如Sup.prototype.xxx = 'xxx'
// 子类,继承父类
class Son extends Parent {
constructor(name, age) {
super(name)
this.age = age
}
say() {
console.log('你好')
super.say()
console.log(`今年${this.age}岁`)
}
}
Son.type = '懒'