关于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. Android Support Library 是什么?

    这两天刚开始学习安卓,这里记录下这两天遇到的一些小问题. 首先先贴一个安卓 API 等级. 官方地址:https://developer.android.com/about/dashboards/ ( ...

  2. HTML中使用<input>添加的按钮打开一个链接

    在HTML中,<form>表单的<input type="button">可以添加一个按钮.如果想让该按钮实现<a> 的超链接功能,需要如下实现 ...

  3. MySQL服务安装

    1.将mysql的安装文件放入服务器里面 2.进行yum源的修改 3.依次安装mysql的5个文件 最后一个server需要的依赖太多,所以用yum进行安装. 或者直接全部用yum进行安装 6.进行m ...

  4. Java_myBatis_一对多映射

    例如我们有需求需要实现以下查询  "一个用户对多条订单编号": select user.*,o.number,o.createtime from user left JOIN or ...

  5. exportfs命令

    exportfs命令:功能说明 :NFS共享管理 语法格式 exportfs [必要参数][选择参数][目录] 功能描述 exportfs 命令:用于管理NFS(Network File System ...

  6. 【收藏】轻松导出全民K歌里任何人录制的短视频(MV)、歌曲的方法

    有一次想把她在全民K歌里唱过的所有歌下载到电脑上,然后合成一个视频.但不知道怎么导出全民K歌里的歌曲,经过各种百度Google终于找到了一个用起来很简单的工具.不仅可以下载保存任何人录制的歌曲,还可以 ...

  7. scala面向对象.高阶函数,柯里化,Actor编程简介

    1.定义一个类 class Person{ //用val修饰的变量是只读属性,有getter但是没有setter val id ="111" //用var修饰的变量既有getter ...

  8. golang结构体

    声明结构体 定义结构体使用struct关键字.在结构体内部定义它们的成员变量和类型.如果成员变量的类型相同还可以把它们写到同一行. struct里面可以包含多个字段(属性) struct类型可以定义方 ...

  9. Linux 4.10.8 根文件系统制作(三)---制作yaffs文件系统

    这里直接用的是韦东山提供的工具. yaffs文件系统是专门用于nandflash的文件系统 我们前面已经下载了yaffs 的源码,也做了文件系统目录的构建. 在yaffs2的源码目录中有一个utils ...

  10. Linux - rm 修复误删文件

    fdisk -l # 分区信息lsblk -f # 查看文件类型/etc/fstab # 查看文件格式挂载启动信息 # debugfs针对 ext2 # ext3grep针对 ext3 # extun ...