New操作符实现原理

为了方便测试与理解,我们先来创建一个构造函数

 function Point(x, y, z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

然后调用我们自己封装的new方法,可以看到实例化对象可以正常打印。

var p = objectFactory(Point, 5, 2, 3)
    console.log(p);

 

再详细介绍它的实现原理之前,需要先理解以下几个方法:

1.Object.creat()

它的官方解释:创建一个新对象,使用现有的对象来提供新创建的对象的proto。

   var obj=null
   obj=Object.create(Point.prototype)
   console.log(obj.__proto__===Point.prototype);  //true

在这里,我们做了两件事:

1.新建了一个空对象obj

2.利用Object.create()的方法,将构造函数的prototyoe指向空对象obj的__proto__

2.Array.from()
  Array.from()是ES6新增的方法,可以将类数组转化为真正的数组。因为类数组虽然具有索引和length等属性,但无法调用数组API。

     当然,比较常用的apply、arguments这些用法就不过多阐述了。如果这些还不熟悉的我相信也不会来看实现原理这些。。

那下面就开始正式实现我们自己的NEW方法了。

   function objectFactory() {
        //1.创建一个空对象
        let newObject = null;
        let arr = Array.from(arguments) //将函数参数转化为数组
        let constructor = arr.shift()   //拿到数组的第一个参数:构造函数
        let result = null;
        // 2.将构造函数的 prototype指向新对象的proto属性
        newObject = Object.create(constructor.prototype);
        //3.将 this 指向新建对象,并执行函数
        result = constructor.apply(newObject, arr);
        // 判断返回对象 
        let flag = result && (typeof result === "object" || typeof result === "function");
        // 4.判断返回结果
        return flag ? result : newObject;
    }

1.首先,创建了空对象newObject:在这个阶段我们将传入的参数对象arguments利用Array.from()转化为了数组。利用shift()弹出了数组的第一个元素,也就是传入的构造函数这个参数。并保存到了变量constructor里。

2.利用Object.create(),将我们上一步拿到的构造函数的prototype指向了新创建的对象newObject

3.通过apply()改变了this指向:此时的this指向了我们新创建的对象newObject。由于第一步时保存了所有参数的arr数组使用过了shift(),所以此时第一个元素(构造函数)已经被弹出,arr里剩下的都是实例化的参数。所以我们将arr作为apply的第二个参数传入,并执行函数。

4.返回最后的结果:由于我们传入的函数不一定都是构造函数,也有可能是一个普通函数。所以需要对最后的结果作一些判断处理。如果返回的是对象或者函数,最后的结果就等于result;如果返回是是基本类型的值,就让它等于这个newObject对象。假设我们取消最后判断,直接输出最后的结果result,执行以下函数

 function test(a, b) {
      
        return a+b
    }
    var t = objectFactory(test, 1, 4)
    console.log(t);   //5

   这里我们传入的是一个普通函数,返回a+b的和。再使用了我们自定义的方法后,直接就输出了结果5,所以此时我们需要将最后的结果指向newObject。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值