面试知识归纳:2.4面向对象
类与实例
js
// 类的声明
function Animal() {
this.name = 'name'
}
// ES6中的类声明
class Animal2 {
constructor() {
this.name = name
}
}
// 生成实例
console.log(new Animal(), new Animal2())类与继承
如何实现继承, 继承的几种方式
- 借助构造函数实现继承 - 将父级构造函数的this指向子构造函数的实例
js
function Parent1() {
this.name = 'parent1'
}
function Child1() {
Parent1.call(this)
this.type = 'child1'
}缺点,父构造函数原型上的方法,属性并没有被继承
- 借助原型链实现继承
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,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 = Child5extend 另一种有效的扩展
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
}
}