关于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()  

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

四、测试

第一种情况:无返回值

    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);

输出结果如下图

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

    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);

输出结果,同上!

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

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);

输出结果,如下:

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

【5分钟一个知识点】JS一文搞懂new操作符的更多相关文章

  1. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...

  2. 一文搞懂 js 中的各种 for 循环的不同之处

    一文搞懂 js 中的各种 for 循环的不同之处 See the Pen for...in vs for...of by xgqfrms (@xgqfrms) on CodePen. for &quo ...

  3. 基础篇|一文搞懂RNN(循环神经网络)

    基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...

  4. Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!

    本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享. 1.引言 典型的Web端即时通讯技术应用场景,主要有以下两种形式 ...

  5. 三文搞懂学会Docker容器技术(中)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 6,Docker容器 6.1 创建并启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] --na ...

  6. 一文搞懂所有Java集合面试题

    Java集合 刚刚经历过秋招,看了大量的面经,顺便将常见的Java集合常考知识点总结了一下,并根据被问到的频率大致做了一个标注.一颗星表示知识点需要了解,被问到的频率不高,面试时起码能说个差不多.两颗 ...

  7. 一文搞懂Flink Window机制

    Windows是处理无线数据流的核心,它将流分割成有限大小的桶(buckets),并在其上执行各种计算. 窗口化的Flink程序的结构通常如下,有分组流(keyed streams)和无分组流(non ...

  8. 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质

    一文搞懂RAM.ROM.SDRAM.DRAM.DDR.flash等存储介质 存储介质基本分类:ROM和RAM RAM:随机访问存储器(Random Access Memory),易失性.是与CPU直接 ...

  9. 一文搞懂 Prometheus 的直方图

    原文链接:一文搞懂 Prometheus 的直方图 Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复 ...

随机推荐

  1. diff目录或文件比较

    转载 2014年12月16日 19:16:54 1937 [功能] 以行的方式比较文本文件的异同处      若要比较目录,则会比较相同文件名的文件[参数]      -b        忽略空格数目 ...

  2. npm脚本

    在package.json的script里面我们可以写很多npm脚本,下面我来总结一下一些日常遇到的知识点: 1.npm_lifecycle_event npm 提供一个npm_lifecycle_e ...

  3. MySQL_select语句(不定时更新)

    1.SELECT语句 select if(fraction>=60 and fraction<=100,'合格','不合格') from sp_employeezzvalidate;

  4. CentOS下安装zookeeper并设置开机自启动

    转自: 一.安装zookeeper # cd /opt/ # mkdir zookeeper # cd zookeeper/ # tar -zxvf zookeeper-3.4.6.tar.gz # ...

  5. go for range

    func main() { var str = "hellow worda" for _, val := range str { fmt.Printf("%q" ...

  6. Nginx 学习笔记(一)如何配置一个安全的HTTPS网站服务器

    一.系统环境 1.系统:Ubuntu 16.04.2 LTS 2.WEB服务器:Openresty11.2.5 二.开始配置 1.获取certbot客户端 wget https://dl.eff.or ...

  7. spring集成ActiveMQ居然要依赖这么多包

    做spring和ActiveMQ的集成,作maven依赖的时候有感(以前都不在乎,现在不一样了........省略) <!-- https://mvnrepository.com/artifac ...

  8. python -- 异步IO 协程

    python 3.4 >>> import asyncio >>> from datetime import datetime >>> @asyn ...

  9. Java实现DOS中的Copy命令

    import java.io.*; import java.util.Scanner; public class fileCopy { public static void main(String [ ...

  10. VUE2.0 饿了吗视频学习笔记(七-终):compute,循环,flex,display:table

    一.star组件使用到了computed属性 computed相当于属性的一个实时计算,当对象的某个值改变的时候,会进行实时计算. computed: { starType() { return 's ...