美文网首页
js new操作符

js new操作符

作者: 神话降临 | 来源:发表于2021-09-08 18:26 被阅读0次

    简单实现

    其实new操作符实现还是很简单的,因为Mdn上总共也就是4句话来描述它的作用

    1. 创建一个空的简单JavaScript对象(即{});
    2. 为步骤1新创建的对象添加属性 proto ,将该属性链接至构造函数的原型对象 ;
    3. 将步骤1新创建的对象作为this的上下文 ;
    4. 如果该函数没有返回对象,则返回this

    我们首先来依次用代码来翻译上面的四句话

    function newOperator() {
      // 创建对象
      const obj = {}
      // 创建的对象添加属性__proto__,并指向构造函数的原型对象
      obj.__proto__ = Constructor.prototype
      // 创建的对象作为this的上下文,并获取返回值
      const ret = Constructor.apply(obj, arguments)
      // 如果该函数没有返回对象,则返回新创建的对象
      return typeof ret === "object" ? ret : obj;
    }
    

    上面的代码已经很好的翻译了上面的四句话,但是我们却不能直接用来创建构造函数的实例,因为我们根本没有把构造函数传进去,即上面的代码是无法运行的,因为Constructor并没有定义

    代码完善

    那么就让我们来重新完善一下上面的代码, 步骤如下:

    • 首先新增参数,即需要实例的构造函数
    function newOperator(ctor) {}
    
    • 判断ctor参数类型,是否是function类型,否则抛出错误
    if (typeof ctor !== "function") {
        throw '参数异常,只接收构造函数'
      }
    
    • 新建实例为对象添加__proto,并指向构造函数的原型对象
      // 创建对象
      const obj = {}
      // 创建的对象添加属性__proto__,并指向构造函数的原型对象
      obj.__proto__ = Constructor.prototype
      
      // 上面的代码等同于如下代码
      const obj = Object.create(ctor.prototype)
      
    
    • 处理参数
      const params = [].slice.call(arguments, 1)
      const result = ctor.apply(obj, params)
    

    此处解释一下为什么要处理一下参数

    function Dog (name, age) {
      this.name = name
      this.age = age
    }
    const maomao = newOperator(Dog, 'maomao', 2)
    

    从上面的代码可以看出来,我们使用newOperator的时候,第一个参数是构造函数,所以需要把第一个参数截取掉,获取到的参数就是['maomao', 2],这两个才是构造函数的参数

    • 改变this上下文并获取构造的返回结果
    const result = ctor.apply(obj, params)
    

    为什么要获取构造的返回结果??

    因为通常来说实现构造函数是不需要return来返回结果的,但是如果真的给构造函数添加return关键字并返回结果,我们也应该返回这个结果,像如下代码

    function Cat(name, age) {
        return {
            name: name,
            age: age
        }
    }
    
    • 判断类型并返回
    const isObject = typeof result === 'object'
      const isFunction = typeof result === 'function'
      if (isFunction || isObject) {
        return result
      }
      return obj
    

    完整代码

    function newOperator(ctor) {
      if (typeof ctor !== "function") {
        throw '参数异常,只接收构造函数'
      }
      const obj = Object.create(ctor.prototype)
      const params = [].slice.call(arguments, 1)
      const result = ctor.apply(obj, params)
      const isObject = typeof result === 'object'
      const isFunction = typeof result === 'function'
      if (isFunction || isObject) {
        return result
      }
      return obj
    }
    

    相关文章

      网友评论

          本文标题:js new操作符

          本文链接:https://www.haomeiwen.com/subject/jwovwltx.html