原型链篇:原型链继承、构造函数继承、组合继承

189 阅读2分钟

原型链继承

// 1.原型链继承(将父类的实例作为子类的原型)
function Parent() {
  this.show = true
  this.info = {
    name: 'xiaoye',
    age: 18
  }
}

Parent.prototype.getInfo = function() {
  console.log(this.info, this.show)
}
function Child() {}
Child.prototype = new Parent()

let child1 = new Child()
child1.info.gender = "男"
child1.getInfo() // {name: 'ywl', age: 18, gender: '男'}

let child2 = new Child()
child2.getInfo() // {name: 'ywl', age: 18, gender: '男'}
child2.show = false
console.log(child2.show) // false
console.log(child1.show) // true

优点:

1.父类的方法可以复用

缺点:

1.父类的引用属性会被所有子类共享,更改一个父类的引用属性,其它子类也会受影响

2.子类型实例不能给父类型构造函数传参

构造函数继承

function Parent() {
  this.info = {
    name: 'xiaoye',
    age: '18'
  }
}

function Child() {
  // 改变Parent构造函数this指向,复制构造函数中属性与方法
  Parent.call(this)
}

let child1 = new Child()
child1.info.job = 'web'

let child2 = new Child()
console.log(child1.info) // {name: 'xiaoye', age: '18', job: 'web'}
console.log(child2.info) // {name: 'xiaoye', age: '18'}

优点:

1.父类引用属性不会被子类共享

2.可以向父类构造函数进行传参

缺点

1.不能继承父类原型上的方法(即不能访问Parent.prototype上定义的方法),因此所有方法属性都写在构造函数中,每次创建实例都

组合继承

function Parent(name) {
  this.name = name
  this.colors = ['red', 'blue', 'yellow']
}

Parent.prototype.sayName = function() {
  console.log(this.name)
}

function Child(name, age) {
  // 继承父类构造函数中的方法和属性并防止引用类型共享
  // 使子类可以向父类传参
  Parent.call(this, name)
  this.age = age
}

// 继承父类原型上的方法
Child.prototype = new Parent()

Child.prototype.sayAge = function() {
  console.log(this.age)
}

let child1 = new Child('xiaoye', 18)
child1.colors.push('green')
console.log(child1.colors) // ['red', 'blue', 'yellow', 'green']
child1.sayName() // xiaoye
child1.sayAge() // 18

let child2 = new Child('xiaoshi', 20)
console.log(child2.colors) // ['red', 'blue', 'yellow']
child2.sayName() // xiaoshi
child2.sayAge() // 20

优点

1.父原型上的方法可以被子类复用

2.父原型的引用属性不会被子类共享

3.实例化时子类可以向父类传递参数

组合继承结合了原型链继承与构造函数继承的优点,解决了彼此使用上的缺点,是项目中我们最常用的一种继承方式