JS中的继承

50 阅读2分钟

1. 原型链继承

function WangJianLin() {
  this.money = "100w"
  this.house=["上海","北京"]
}
function WangSiCong(){
this.girls = ['豆豆','雪梨']
}
// 王思聪用原型来继承王健林实例
WangSiCong.prototype = new WangJianLin()

问题:

  • 包含引用类型值的原型属性会被所有实例共享
// 创建两个王思聪实例,改变第一个实例的原型属性(引用类型),第二次创建出来的该原型属性也会被改变
let w1 = new WangSiCong()
    w1.prototype.house.push("深圳")
    
let w2 = new WangSiCong()
console.log(w1.prototype.house,w2.prototype.house)  // ["上海", "北京", "深圳"]  ["上海", "北京", "深圳"]
  • 创建子类型的实例时,不能向超类型的构造函数中传递参数,没办法再不影响所有对象实例的情况下给超类型的构造函数传递参数

2. 借用构造函数继承

优势

  • 可以由子类型构造函数中向超类型构造函数传递参数
 function WangJianLin(son) {
  this.money = "100w"
  this.house=["上海","北京"]
  this.son= son
}
function WangSiCong(){
this.girls = ['豆豆','雪梨']
// 继承了王建林
WangJianLin.call(this)
// 传递参数
WangJianLin.call(this,'王思聪')
} 

问题

  • 不能函数复用

3. 组合继承

 function WangJianLin(name) {
  this.money = "100w"
  this.house=["上海","北京"]
  this.name= name
}
WangJianLin.prototype.sayName = function(){
    alert(this.name)
}
function WangSiCong(name,age){
WangJianLin.call(this,name)  // 构造函数继承  第二次调用 WangJianLin()
this.age = age
} 
// 原型替换继承
WangSiCong.prototype = new WangJianLin()   // 第一次调用 WangJianLin()
WangSiCong.prototype.constructor = WangSiCong
WangSiCong.prototype.sayAge = function(){
    alert(this.age)
}
var w1 = new WangSiCong("思聪1",33)
w1.house.push('深圳')
w1.sayName()
w1.sayAge()
var w2 = new WangSiCong("思聪2",22)
w2.sayName()
w2.sayAge()
console.log(w1.house,w2.house) 

问题

  • 调用两次超类型构造函数

4. 原型式继承

在object()函数内部,先创建一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例

function object(o) {
function F(){}
F.prototype = o
return new F()
}

Object.create()方法规范了原型式继承 两个参数,一个参数是用作新对象原型的对象 (可选) 一个是为新对象定义额外属性的对象

5. 寄生式继承

function crearteAnther(original){
var clone = object(orignal)  // 通过调用函数创建一个新对象
clone.sayHi = function(){    // 以某种方式增强这个对象
alert('hi')
}
return clone    // 返回这个对象
}

举例

var person = {
    name:'王思聪',
    girls:['雪梨','豆豆']
}
var anthoerPerson = crearteAnther(person)
anthoerPerson.sayHi()

问题

  • 不能函数复用

5. 寄生组合式继承

  1. 创建超类型原型的一个副本
  2. 为创建的副本添加constructor属性,弥补因重写原型而失去默认的constructor属性
  3. 将新创建的对象赋值给子类型的原型
function inheritPrototype(subType,superType){
    var prototype = object(superType.prototype)   // 创建对象
    prototype.constructor = subType    // 增强对象
    subType.prototype = prototype    // 指定对象
}```
举例

```javascript
function SuperType(name){
   this.name = name
   this.colors =["red","blue","green"]
}
SuperType.prototype.sayName =function(){
    alert(this.name)
}
function SubType(name,age){
    SuperType.call(this,name)
    this.age = age
}
inheritPrototype(SubType,SuperType)
SubType.prototype.sayAge = function(){
    alert(this.age)
}
var instance = new SubType('Mary',20)
console.log(instance);