lxinr/interview-question

2021/01/28 - 实现一个new

lxinr opened this issue · 0 comments

lxinr commented

在使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作:

  1. 创建(或者说构造)一个全新的对象
  2. 这个新对象会被执行[[prototype]]连接
  3. 这个新对象会绑定到函数调用的this
  4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象

因此实现如下:

function createNew () {
  // 获取构造函数及参数
  const [Con, ...args] = [...arguments]
  // 创建一个空的对象
  const obj = new Object()
  obj.__proto__ = Con.prototype // 将对象链接到构造函数的原型上,这样 obj 就可以访问到构造函数原型中的属性
  // 或者直接使用
  const obj = Object.create(Con.prototype)
  
  const ret = Con.apply(obj, args) // 改变构造函数的this指向到obj,这样 obj 就可以访问到构造函数中的属性
  // 需判断构造函数是否存在返回值,如果返回值是个对象(非null),则返回该对象,否则返回obj
  return ret instanceof Object ? ret : obj // 或者 typeof ret === 'object' ? ret || obj : obj
}

// 使用
function Person (info) {
  console.log('person---', info) 
}

createNew(Person, { v: 20 })