blog icon indicating copy to clipboard operation
blog copied to clipboard

JS模拟实现new

Open BlingSu opened this issue 4 years ago • 0 comments

首先要知道 new 做了什么

  1. 创建一个新的对象,并且继承构造函数的 prototype ,这里是为了继承构造函数原型上的属性和方法
  2. 执行构造函数,方法内的 this 被指定为该新实例,这是为了执行构造函数内的赋值操作
  3. 返回新实例,如果构造函数方法返回一个对象,那么返回该对象,否则返回第一步创建的新对象
// new 是关键字,可以模拟 new Foo(args) = myNew(Foo, args)
function myNew (foo, ...args) {
  /**
   * 创建新对象,并继承构造方法的prototype属性
   * 把 obj 挂载在原型链上,相当于 obj.__proto__ = Foo.prototype
  */
  let obj = Object.create(foo.prototype)
  /**
   * 执行构造方法,绑定this
   * 让构造方法能进行 this.name = name 的操作,args是构造方法入参
   * 这里用myNew模拟,所以入参从myNew传入
  */
  let result = foo.apply(obj, args)
  return Object.prototype.toString.call(result) === '[object Object]' ? result: obj
}

测试

function Foo (name) {
  this.name = name
}
const newObj = myNew(Foo, 'haha')
console.log(newObj)
console.log(newObj instanceof Foo)
const oldObj = new Foo('haha2')
console.log(oldObj)
console.log(oldObj instanceof Foo)

BlingSu avatar Nov 03 '20 03:11 BlingSu