ChuChencheng / note

菜鸡零碎知识笔记
Creative Commons Zero v1.0 Universal
3 stars 0 forks source link

JavaScript 实现 new 操作符 #7

Open ChuChencheng opened 4 years ago

ChuChencheng commented 4 years ago

new 操作都做了什么

以下复述一遍 MDN 中的解释:

  1. 创建一个新的对象
  2. 将创建的对象的原型指向构造函数的原型(instance.__proto__ = F.prototype
  3. 将新对象作为 this 执行一遍构造函数
  4. 如果构造函数有返回对象,则返回,否则返回新创建的对象

最简单的实现

根据以上定义,得到一个最简单的实现:

function _new (F, ...args) {
  const obj = Object.create(F.prototype)
  const ret = F.apply(obj, args)
  return typeof ret === 'object' ? ret : obj
}

不足

以上最简单的实现有几个方面没有考虑:

  1. 未判断 F 是否满足构造函数,即是否可以 new
  2. 返回值光靠 typeof ret === 'object' 是不够的
  3. new.target 需要赋值

改进

判断 F 是否满足构造函数

function isConstructor (f) {
  if (f === Symbol) return false
  try {
    Reflect.construct(String, [], f)
  } catch (e) {
    return false
  }
  return true
}

判断返回值

因为 typeof null === 'object' // truetypeof (function () {}) === 'function' // true 所以要对这两种类型另外判断:

function isESObject (returnValue) {
  return (typeof returnValue === 'object' && typeof returnValue !== null) || typeof returnValue === 'function'
}

new.target 处理


以上改进内容参照 https://github.com/francecil/leetcode/issues/11 ,有关 new.target 的内容可到此链接查看