关于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. 一起使用mock数据动态创建表格

    在ant-design中,我们创建一个基础table会怎么实现呢? 如下代码可视,我们会自己创建一些数据,在表格中渲染出来,如下 <Card title="基础表格"> ...

  2. EClipse for PHP 中文乱码问题

    UTF-8 格式的php,中文都是乱码. 如果此时在EClipse中输入中文会有 CP1252 错误( CP1252不支持xxxx ) 解决方法: windows->preferences-&g ...

  3. springcloud的配置文件的读取顺序

    SpringBoot默认支持properties和YAML两种格式的配置文件.前者格式简单,但是只支持键值对.如果需要表达列表,最好使用YAML格式.SpringBoot支持自动加载约定名称的配置文件 ...

  4. CodeForces701E DFS

    http://codeforces.com/problemset/problem/701/E 一个显而易见的方法是考虑点的贡献,一次dfs记录到所有根节点不考虑匹配的答案,再一次dfs反向推出答案 # ...

  5. pyautogui_pdf批量转换为TXT

    pyautogui_pdf批量转换为TXT, 用pdf自带无损转换 # -*- coding: utf-8 -*- """ Created on Thu May 5 15 ...

  6. selenium_采集药品数据

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...

  7. xgboost应用

    在业务中,我们经常需要对数据建模并预测.简单的情况下,我们采用 if else 判断(一棵树)即可.但如果预测结果与众多因素有关,而每一个特征的权重又不尽相同. 所以我们如何把这些特征的权重合理的找出 ...

  8. JVM总结(六):早期(编译期)优化

    这节我们来总结一下JVM编译器优化问题. JVM编译器优化 Javac编译器 Javac的源码和调试 解析与填充符号表 注解处理器 语法分析与字节码生成 Java语法糖 泛型和类型擦除 自动装箱.拆箱 ...

  9. js通用绑定事件函数

  10. 单例设计模式Singleton之懒加载模式(懒汉模式)【原】

    单例设计模式Singleton之懒加载模式(懒汉模式) SingletonLazy.java类 package kingtool; import kingtool.http.IPTool; publi ...