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

输出结果,如下:

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

最新文章

  1. asp.net的快捷实用分页类
  2. 高通平台FastMMI(FFBM模式)简介与进入方法
  3. C#简易一元二次求解器
  4. jquery中html(), text(),val()区别(zhuan)
  5. 93、App Links (应用程序链接)实例
  6. 设置su和sudo为不需要密码
  7. Poj 1006 / OpenJudge 2977 1006 Biorhythms/生理周期
  8. Win32 GDI基础(笔记)
  9. Ubuntu 组态 Tomcat而每天的错误解决
  10. Flask architecture
  11. ORA-06575:程序包或函数处于无效状态
  12. 在OS X 10.9配置WebDAV服务器联合NSURLSessionUploadTask实现文件上传
  13. Bulk API
  14. 「造个轮子」——cicada 源码分析
  15. 6-2 Verbs and Adjectives with that clauses
  16. web print
  17. C# 数组转json
  18. C#回调浅析(委托、接口回调)
  19. oracle第一天笔记
  20. JAVA 实验报告

热门文章

  1. zoj3707(Calculate Prime S)解题报告
  2. & 引用传值
  3. pyautogui_pdf内容提取到excel内_3
  4. CentOS Linux release 7.3源码安装zabbix
  5. 记录一次nginx的upstream的配置信息
  6. vue基础篇---修改对象或数组的值,页面实时刷新
  7. JAVA-集合类型Set常用操作例子(基础必备)
  8. Thread的setDaemon(true)方法
  9. HDU - 4370 0 or 1
  10. kruskal算法:POJ No.3723 Conscription_最小生成树应用_最大权森林