面试官:怎么实现一个new方法

114 阅读1分钟

需要实现的效果如下:

function Dog(name){
  this.name = name
}
Dog.prototype.bark = function(){
  console.log('wangwang');
}
Dog.prototype.sayName = function(){
  console.log('my name is '+ this.name);
}
// 需要实现的效果:
let sanmao = _new(Dog, '三毛')
sanmao.bark()  // 'wangwang'
sanmao.sayName()  // 'my name is 三毛'

new方法主要做了四件事:

  1. 新建一个空对象;
  2. 把新对象的原型指向构造函数的原型;
  3. 把构造函数内部的 this 指向这个空对象;
  4. 执行构造函数, 返回结果是函数或对象返回, 否则返回空对象.
function _new(Func, ...args){
  // 1. 创建实例对象
  // 这种方式IE下是不兼容的
  // let obj = {}
  // obj.__proto__ = Func.prototype  
  // 兼容方案
  let obj = Object.create(Func.prototype)
  // 2. 执行类,把this指向实例对象,并拿到执行结果
  let result = Func.call(obj, ...args)
  // 3. 判断返回结果是对象或函数则把结果返回,否则返回当前的实例对象, 即obj
  if(result !== null && /^(object|function)$/i.test(typeof result)) return result
  return obj
}