欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【5分钟一个知识点】JS一文搞懂new操作符

程序员文章站 2022-04-13 15:20:57
关于new操作符,看了两本书《Javascript高级程序设计3》和《你不知道的JS上》,以及其他文档后,终于豁然开朗。 现总结如下,希望同样懵逼的你,彻底理解它。 如果有不同的意见,欢迎留言讨论。 一、先看看两本书中的定义 《Javascript高级程序设计3》 第145页 1)创建一个新对象 2 ......

        关于new操作符,看了两本书《javascript高级程序设计3》和《你不知道的js上》,以及其他文档后,终于豁然开朗。

现总结如下,希望同样懵逼的你,彻底理解它。

        如果有不同的意见,欢迎留言讨论。

一、先看看两本书中的定义

     《javascript高级程序设计3》 第145页

1)创建一个新对象

2)将构造函数的作用域赋给新对象(因此this指向了这个新对象)

3)执行构造函数中的代码(为这个新对象添加属性)

4)返回新对象

  《你不知道的js上》第91页

1)创建(或者说构造)一个全新的对象

2)这个新对象会被执行[[prototype]]连接

3)这个新对象会绑定到函数调用的this

4)如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象

二、那么,new到底做了什么?

        简单来讲,它主要做了四步

1)创建一个新对象

2)将构造函数的prototype赋值给新对象的__proto__

3)构造函数中的this指向新对象,并且调用构造函数

4)如果构造函数无返回值,或者不是引用类型,返回新对象;否则为 构造函数的返回值。

       ps:这里的引用类型,不清楚的,参见《高程3》的第5章;

三、自己手动实现new()  

 1 function new(){     
 2         var tmp_arr = array.from(arguments);
 3         var func =tmp_arr[0];
 4         //1、创建一个新对象:obj
 5         var obj = {};
 6         //2、将构造函数的prototype赋值给新对象的__proto__
 7         obj.__proto__ = func.prototype;
 8         //3、将构造函数的this指向新对象obj,并且调用这个新对象
 9         var result = func.apply(obj,tmp_arr.slice(1,tmp_arr.length));
10         //如果返回值不是引用类型,返回obj。 否则返回 result
11         return result instanceof object ? result : obj;
12 }

四、测试

第一种情况:无返回值 

【5分钟一个知识点】JS一文搞懂new操作符
    function new(){
        var tmp_arr = array.from(arguments);
        var func =tmp_arr[0];
        var obj = {};
        obj.__proto__ = func.prototype;
        var result = func.apply(obj,tmp_arr.slice(1,tmp_arr.length));
        return result instanceof object ? result : obj;
    }
    function  func(name) {
        this.name = name;
    }
    var f1 = new func('f1');
    console.log(f1);
    var f2 = new(func,'f2');
    console.log(f2);
view code

 输出结果如下图
【5分钟一个知识点】JS一文搞懂new操作符

第二种情况:返回一个非引用类型

【5分钟一个知识点】JS一文搞懂new操作符
    function new(){
        var tmp_arr = array.from(arguments);
        var func =tmp_arr[0];
        var obj = {};
        obj.__proto__ = func.prototype;
        var result = func.apply(obj,tmp_arr.slice(1,tmp_arr.length));
        return result instanceof object ? result : obj;
    }
    function  func(name) {
        this.name = name;
        return true; //非引用类型
    }
    var f1 = new func('f1');
    console.log(f1);
    var f2 = new(func,'f2');
    console.log(f2);
view code

 输出结果,同上!

 

第三种情况:返回一个引用类型,我们返回当前的日期 ;

【5分钟一个知识点】JS一文搞懂new操作符
function new(){
        var tmp_arr = array.from(arguments);
        var func =tmp_arr[0];
        var obj = {};
        obj.__proto__ = func.prototype;
        var result = func.apply(obj,tmp_arr.slice(1,tmp_arr.length));
        return result instanceof object ? result : obj;
    }
    function  func(name) {
        this.name = name;
        return new date(); //返回当前时间
    }
    var f1 = new func('f1');
    console.log(f1);
    var f2 = new(func,'f2');
    console.log(f2);
view code

输出结果,如下:

 【5分钟一个知识点】JS一文搞懂new操作符 

可以看出:我们的模拟的方法是正确的。