前端面试 - 手写继承

667 阅读1分钟

必备知识

Object.create()

Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。 (请打开浏览器控制台以查看运行结果。)

Object.assign()

Object.assign()  方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

Function.prototype.call()、Function.prototype.apply()、Function.prototype.bind()

区别:

  • call()、apply()直接执行函数,bind()返回新函数,需要手动调用。
  • call()接受参数列表,apply()接受参数数组

手写继承

构造函数继承

缺点:原型链上的方法和属性没办法继承

function Person() { ... } 
Person.prototype.name = 'Person'
function Student() { 
    Person.call(this) // 执行Person,将this指向当前环境 
    ...
}

const s1 = new Student()
console.log(s1.name) // undefined

原型链继承

缺点:实例化原型对象的属性是引用类型的时候,数据互相影响

function Person() {
    this.arr = [1, 2, 3, 4]
} 
function Student() { ... } 
Student.prototype = new Person() // 将构造函数的原型对象指向父函数的实例对象

const s1 = new Student()
const s2 = new Student()
s1.arr.push(5)

console.log(s1.arr) // [1, 2, 3, 4, 5]
console.log(s2.arr) // [1, 2, 3, 4, 5]

组合继承

参考文档

⚠️ 重点:

  • 执行父函数时,this 的指向问题
  • 子函数原型对象指向,需构造新对象
  • 修正指向
// 继承单个对象
function Person() { ... } 
function Student() { 
    Person.call(this) // 执行Person,将this指向当前环境 ... 
} 
Student.prototype = Object.create(Person.prototype) // 利用Object.create创建新对象
Student.prototype.constructor = Student // 修正指向 

// 继承多个对象【混入】 
function Person() { ... } 
function Behavior() { ... } 
function Student() { 
    Person.call(this) Behavior.call(this) 
    ... 
} 
Student.prototype = Object.create(Person.prototype) 
Object.assign(Student.prototype, Behavior.prototype) // Object.create和Object.assign都是生成一个新的对象,来避免引用类型相互影响
Student.prototype.constructor = Student // 修正指向