Skip to content

面试知识归纳:2.4面向对象

类与实例

js
// 类的声明
function Animal() {
  this.name = 'name'
}
// ES6中的类声明
class Animal2 {
  constructor() {
    this.name = name
  }
}
// 生成实例
console.log(new Animal(), new Animal2())

类与继承

如何实现继承, 继承的几种方式

  1. 借助构造函数实现继承 - 将父级构造函数的this指向子构造函数的实例
js
function Parent1() {
  this.name = 'parent1'
}
function Child1() {
  Parent1.call(this)
  this.type = 'child1'
}

缺点,父构造函数原型上的方法,属性并没有被继承

  1. 借助原型链实现继承
js
function Parent2() {
  this.name = 'parent2'
}
function Child2() {
  this.type = 'child2'
}
Chil2.prototype = new Parent2()

缺点:

js
function Parent2() {
  this.name = 'parent2'
  this.players = [1,2,3]
}
function Child2() {
  this.type = 'child2'
}
Chil2.prototype = new Parent2()
let c1 = new Child2()
let c2 = new Child2()
console.log(c1.players, c2.players) // [1,2,3] [1,2,3]
c2.players.push(4) // c2.players [1,2,3,4]   c1.players [1,2,3,4]

原型链中的原型对象也是共用的

  1. 组合方式实现继承, 1,2方法结合在一起
js
function Parent3() {
  this.name = 'parent3'
  this.players = [1,2,3]
}
function Child3() {
  Parent3.call(this)
  this.type = 'child3'
}
Child3.prototype = new Parent3()
let c3 = new Child3()
let c4 = new Child4()
c3.players.push(4)
console.log(c3.players, c4.players) // [1,2,3,4] [1,2,3]

缺点:

在实例化子类时。父类的构造方法执行了2次,首先在 Parent3.call(this) 时执行一次,在new时,又执行了一次

3.1 组合继承的优化

js
function Parent4() {
  this.name = 'parent4'
  this.players = [1,2,3]
}
function Child4() {
  Parent3.call(this)
  this.type = 'child4'
}
Child4.prototype = Parent4.prototype
let c5 = new Child3()
let c6 = new Child4()
c5.players.push(4)
console.log(c5.players, c6.players)

缺点: 破坏了constructor指向

console.log(s5.constructor) // Parent4

3.2 组合继承的优化,解决constructor指向

js
function Parent5() {
  this.name = 'parent5'
  this.players = [1,2,3]
}
function Child5() {
  Parent5.call(this)
  this.type = 'child5'
}
Child5.prototype = Object.create(Parent5.prototype)
Child5.prototype.constructor = Child5

extend 另一种有效的扩展

js
function extend(subClass, superClass) {
  let F = function() {}
  F.prototype = superClass.prototype
  subClass.prototype = new F()
  subClass.prototype.constructor = subClass

  subClass.superClass = superClass.prototype
  if (superClass.prototype.constructor == Object.prototype.constructor) {
    superClass.prototype.constructor = superClass
  }
}

共 20 个模块,1301 篇 Markdown 文档。