本篇博客接着继承的这6种方式!(上),继续介绍你想知道的后三种继承方式,尤为是最理想的寄生组合式继承。函数
原型式继承的基本思想:post
//基础对象
var person = {
name: "一灯",
arr: [1,2,3]
}
//Object.create()建立新对象,传入基础对象
var son1 = Object.create(person)
son1.name = "AAA"
son1.arr.push(4)
console.log(son1.name) //AAA
var son2 = Object.create(person)
son2.name = "BBB"
console.log(son2.name) //BBB
console.log(son2.arr) //1,2,3,4,引用类型问题依然存在
复制代码
固然你也能够使用Object.create()的第二个参数传添加对象属性ui
var person = {
name: "一灯",
arr: [1,2,3]
}
var son1 = Object.create(person, {
name: {
value: "AAA"
}
})
son1.arr.push(4)
console.log(son1.name) //AAA
var son2 = Object.create(person, {
name: {
value: "BBB"
}
})
console.log(son2.name) //BBB
console.log(son2.arr) //1,2,3,4
复制代码
原型式继承解决了原型链没法传参的问题,而且无需使用构造函数(避免了构造函数的问题)。所以在不必使用构造函数时能够采用这种方法。this
引用类型问题依旧存在spa
寄生式继承能够理解为是原型式继承的加强。在原型式继承中咱们建立了一个新对象,寄生式继承即是在新对象中添加方法,以加强对象。prototype
var person = {
name: "一灯",
arr: [1,2,3]
}
//加强对象
function increase(obj, prop) {
var object = Object.create(obj,prop)
object.getName = function() {
console.log(this.name)
}
return object
}
var son1 = increase(person, {
name: {
value: "AAA"
}
})
son1.arr.push(4)
console.log(son1.name) //AAA
son1.getName() //AAA
var son2 = increase(person, {
name: {
value: "BBB"
}
})
console.log(son2.name) //BBB
console.log(son2.arr) //1,2,3,4
son2.getName() //BBB
复制代码
寄生式继承相似于构造函数,每一个实例对象都有一个副本——破坏了复用性。code
在继承的这6种方式!(上)中讲到的组合式继承比较经常使用的一种方式,然而这种方式仍是存在一个问题——父级构造函数调用了两次(能够到上篇博文查看代码)。一次在建立子级原型对象,另外一次在子级构造函数内部。对象
对于精益求精的码农,固然不能容忍,所以诞生了寄生组合式继承,其核心思想是:继承
function inheritPrototype(Son, Father) {
//建立一个Father.prototype的副本
var prototype = Object.create(Father.prototype)
/*下面这句代码的不少资料的描述感受不太清晰,个人理解: *一、Father.prototype的做用是赋值给Son.prototype *二、若是没有下面这条语句:Son.prototype.constructor == Father构造函数 *三、所以须要更改Son.prototype.constructor,模拟new Father()的过程 */
prototype.constructor = Son
//把Father.prototype赋值给 Son.prototype
Son.prototype = prototype
}
function Father(name) {
this.name = name
this.arr = [1,2,3]
}
Father.prototype.getName = function() {
console.log(this.name)
}
function Son(name, age) {
Father.call(this, name)
this.age = age
}
inheritPrototype(Son, Father)
Son.prototype.getAge = function() {
console.log(this.age)
}
var son1 = new Son("AAA", 23)
son1.getName() //AAA
son1.getAge() //23
son1.arr.push(4)
console.log(son1.arr) //1,2,3,4
var son2 = new Son("BBB", 24)
son2.getName() //BBB
son2.getAge() //24
console.log(son2.arr) //1,2,3
复制代码
寄生组合式继承对于引用类型的继承来讲是最理想的继承方式:避免了应用类型问题,而且只调用一次父级构造函数。原型链
要说其缺点就是比其余方式更为复杂一些
- 原型链:最原始的继承方式(引用类型值相互影响、没法向父级构造函数传参)
- 借用构造函数:解决原型链的问题,但破坏了复用性
- 组合式:原型链+借用构造函数(取长避短),但调用了两次父级构造函数
- 原生式:解决原型链传参问题,而且无需使用构造函数,但也存在引用类型问题
- 寄生式:原生式的加强
- 寄生组合式:寄生式+组合式,解决了各类问题,只是代码稍微复杂
更多优质文章将持续更新,来关注一波……