这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战
继承
接着上篇文章讲的几种继承方式(原型链继承,构造函数继承,组合继承),这篇文章继续讲剩下的继承方式。
原型式继承
原型式继承,通过定义一个普通函数,然后把继承的对象通过参数传入,在普通函数内部,新建一个构造函数,把传入的继承对象赋值给它的原型对象,最后返回这个构造函数的实例,最后达到继承的目的。
function fn (o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
var o = {
name: 'a'
}
var a = fn(o)
console.log(a.name) // a
这个原型式继承可以根据传入的对象不同,然后实例继承的就不一样。
es5新增了Object.create方法,和原型式继承的逻辑基本类似。
var o = {
name: 'a'
}
var a = Object.create(o)
console.log(a.name) // a
寄生式继承
寄生式继承,是在原型式继承的基础上,又多了一个普通函数,参数是把继承的对象传入,然后在内部利用原型式继承返回实例,然后还可以给实例本身加上属性/方法。 /方法。
function fn (o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
function wrap (o) {
var instance = fn(o)
instance.name = 'aa'
instance.getName = function() {
return this.name
}
return instance
}
var o = {
name: 'a'
}
var a = wrap(o)
console.log(a.name) // aa
console.log(a.getName()) // aa
寄生组合式继承
寄生组合式继承这个是结合寄生式继承和构造函数继承形成的继承,通过构造函数继承父类本身的属性/方法,通过寄生式继承父类原型的上的属性/方法。
function Son () {
Father.call(this)
}
function Father () {
this.name = 'father'
}
Father.prototype.getName = function () {
return this.name
}
function fn (o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
function wrap (son, father) {
var prototype = fn(father.prototype)
son.prototype = prototype
son.constructor = son
}
wrap(Son, Father)
var p = new Son()
console.log(p) // Son {name: 'father',...}
console.log(p.getName())
es6的继承
es6新增了类class,class的继承是通过extends和super两个关键字来完成。
class Father {
constructor (name, age) {
this.name = name
this.age =age
}
getName () {
return this.name
}
}
class Son extends Father {
constructor (...args) {
super(...args)
}
}
var p = new Son('答案cp3', 18)
console.log(p.getName()) // 答案cp3
console.log(p.age) // 18
可以看到实例继承了父类的name和age字段,传入参数直接生效。
目前还是推荐可以使用es6的class,可读性强,操作方便。
更详细的class的继承可以看我之前这篇文章。