JavaScript -- new 操作符模拟实现原理

构造函数创建实例化对象时必须使用 new 关键字,new 操作符到底做了什么事情,又是怎么实现的?

MDN 上的讲解:

new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

new 关键字会进行如下的操作:

  • 创建一个空的简单JavaScript对象(即{});
  • 链接该对象(即设置该对象的构造函数)到另一个对象 ;
  • 将步骤1新创建的对象作为this的上下文 ;
  • 如果该函数没有返回对象,则返回this。

先来看 使用new 创建实例对象的例子:


   let that
    function Person(name,age) {
        this.name = name
        this.age=age
        that=this
    }
    let person=new Person('bjt',18)
    console.log('实例对象',person)
    console.log(person===that)//true

从运行结果可以看出,构造函数中的 this 与实例化对象是同一个对象,并且实例化对象可以继承 构造函数 prototype 上的属性和方法,对于上面的第四点:如果该函数没有返回对象,则返回this。如果函数有返回值的话,结果会是什么样呢?看下面例子:

let that
    function Person(name,age) {
        this.name = name
        this.age=age
        that=this
        // return 1 //没有影响
        // return 'ljy'//没有影响
        // return {name:'newObj'}//实例对象 {name: "newObj"} false
        // return [1,2,3,4]//实例对象 (4) [1, 2, 3, 4] false
    }
    let person=new Person('bjt',18)
    console.log('实例对象',person)
    console.log(person===that)

说明如果构造函数中有返回值,且返回值是Object 类型数据时,使用 new 创建的对象就是该返回值,如果是原始值类型的数据则不受影响,实例化对象仍是 new 创建的那个对象。

总结:
1、创建一个新的空对象
2、将该对象的__proto__ 指向构造函数的prototype,该对象就可以继承构造函数原型对象上的属性和方法
3、将构造函数的 this 指向该对象并调用构造函数
4、判断构造函数的返回值,是Object 类型数据就返回,不是就返回创建的这个对象

模拟实现的代码:

   //模拟实现 new 操作符
    function create(con,...args) {
        let obj={}//新建一个空对象
        Object.setPrototypeOf(obj,con.prototype)//将该对象的__proto__指向 构造函数的原型
        let result=con.apply(obj,args)//改变构造函数中的this指向,使用该obj来调用获得属性和方法
        //判断构造函数return值是否为对象
        return result instanceof Object ? result : obj

    }
    let that
    function Person(name,age) {
        this.name = name
        this.age=age
        that=this

    }
    let person=create(Person,'bjt',18)
    console.log('实例对象',person)//实例对象 Person {name: "bjt", age: 18}
    console.log(person===that)//true

参考示意图:(并不完全准确)
JavaScript -- new 操作符模拟实现原理_第1张图片

参考文章:

  • 重学 JS 系列:聊聊 new 操作符
  • JavaScript深入之new的模拟实现

你可能感兴趣的:(面试复习,js)