Skip to content

new & call & bind ​

new ​

js
function myNew(Constructor, ...args) {
  // 1. 创建新对象,原型链指向构造函数的 prototype
  const obj = Object.create(Constructor.prototype)
  // 2. 用新对象做 this,执行构造函数
  const result = Constructor.apply(obj, args)
  // 3. 如果构造函数返回对象,用返回的对象;否则用新对象
  return result instanceof Object ? result : obj
}

面试要点:

  • Object.create() vs { __proto__: ... }
  • 构造函数返回对象时,用返回的对象而非新对象
  • 构造函数返回基本类型时,忽略,用新对象

call ​

js
Function.prototype.myCall = function(context = window, ...args) {
  const fnKey = Symbol('fn')
  context[fnKey] = this
  const result = context[fnKey](...args)
  delete context[fnKey]
  return result
}

要点:用 Symbol 避免属性冲突

apply ​

js
Function.prototype.myApply = function(context = window, args = []) {
  const fnKey = Symbol('fn')
  context[fnKey] = this
  const result = context[fnKey](...args)
  delete context[fnKey]
  return result
}

bind ​

js
Function.prototype.myBind = function(context, ...outerArgs) {
  const self = this
  const bound = function(...innerArgs) {
    return self.apply(
      // new 绑定优先:通过 new 调用时,this 指向实例
      this instanceof bound ? this : context,
      [...outerArgs, ...innerArgs]
    )
  }
  // 继承原型
  bound.prototype = Object.create(self.prototype)
  return bound
}

面试要点:

  • 返回新函数
  • 支持预设参数(柯里化)
  • new 绑定优先级 > bind 绑定
  • 原型继承

基于 Vue 2.7 & Vue 3.4 源码