zoukankan      html  css  js  c++  java
  • 【5分钟一个知识点】JS一文搞懂new操作符

            关于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 }

    四、测试

    第一种情况:无返回值 

        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

     输出结果如下图

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

        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

     输出结果,同上!

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

    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

    输出结果,如下:

      

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

  • 相关阅读:
    500 cannot be cast to javax.xml.registry.infomodel
    mybatis
    [Nest] 02.nest之控制器
    [React] react-interview-01
    [JavaScript] es6规则总结
    [JavaScript] Date对象
    [Vue] vuex-interview
    [Vue] vue-router-interview
    [Vue] vue的一些面试题4
    [Vue] vue的一些面试题3
  • 原文地址:https://www.cnblogs.com/lanleiming/p/10191592.html
Copyright © 2011-2022 走看看