美文网首页
javascript 中new关键字到底做了什么事情

javascript 中new关键字到底做了什么事情

作者: 默默无闻的小人物 | 来源:发表于2021-09-26 13:59 被阅读0次

    1.首先创建了一个空对象,这个对象将会作为执行构造函数之后返回的对象实例。

    2.使上面创建的空对象的原型(proto)指向构造函数的prototype属性。

    3.将这个空对象赋值给构造函数内部的this,并执行构造函数逻辑。

    4.根据构造函数执行逻辑,返回第一步创建的对象或构造函数的显式返回值。


    因为new是JavaScript的关键字,因此不能直接将其覆盖,但是可以通过实现一个函数newFunc来进行模拟。预期对newFunc的使用方式如下:

    function Person(name){
      this.name=name
    }
    const person = new newFunc(Person,'fzs')
    console.log(person)
    // 输出 {name:'fzs'}
    

    现在我们来实现一个newFunc,代码如下

    function newFunc(...args){
        // 取出args数组的第一个参数,即目标的构造函数
        const constructor = args.shift()
        
        //创建一个空对象,且使这个对象继承构造函数的prototype属性
        //即实现  obj._prot_ ===  constructor.prototype
        const obj = Object.create(constructor.prototype)
    
        // 执行构造函数,得到构造函数返回结果
        // 注意,这里使用 apply 使构造函数的 this 指向 obj
        const result = constructor.apply(obj,args)
    
        // 如果构造函数执行后,返回结果是对象类型,则直接将该结果返回。否则返回obj对象
        return (typeof result === 'object' && result!=null)
    }
    

    上述代码并不复杂,涉及到的几个关键点如下:

    • 使用 Object.create 使 obj 的 proto 指向构造函数的原型。
    • 使用 apply 方法使构造函数内的this指向 obj
    • 在newFunc返回时, 使用三目运算符决定返回结果。

    下面来看一下构造函数如果有显式返回值的时候

    function Person(name){
      this.name=name
      return  {1:1}
    }
    
    console.log(person)
    

    看上面输出可以知道,构造函数如果有显示返回值,且返回值为对象类型的话,那么构造函数返回结果就不再是目标实例了。所以我们在实现newFunc的时候要注意下这些注意点

    另外一个注意点:不要使用箭头函数来做构造函数

    image.png

    因为箭头函数没有 prototype ,也没有this 跟 arguments对象。所以有涉及到 this 跟 arguments 不要使用箭头函数

    另外构造函数的原型方法需要通过 this 获得实例,因此箭头函数不可以出现在构造函数的原型方法上,下面就是错误用法

    // 错误用法1
    Person.prototype = () => {
     // .....
    }
    // 错误用法2
    const person = {
     name: 'fzs',
     getName:() => {
       console.log(this.name)
     }
    }
    person.getName()
    

    上述错误用法2中,getName函数体内的this其实是指向window,所以不符合其用意。举一反三吧。知道以上的注意点之后。再去理解

    相关文章

      网友评论

          本文标题:javascript 中new关键字到底做了什么事情

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