JavaScript中的new()做了些什么
2020-01-03 本文已影响0人
agamgn
前言
一句话介绍new:
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一
是不是有点难懂,没关系。我们从一道面试题说起:
demo1.png 是的,没有运行代码前,我以为是"amagn"。现在我们修改下代码: demo2.png 很显然,输出的结果是 'amagn', 但是有 new 存在呢?接着看下去
new的作用
我们先来通过两个例子来了解 new 的作用: demo3.png通过代码的运行结果,我们可以得出结论:
- 通过new创建出来的实例可以访问到构造函数中的属性。
- 通过new出来的实例可以访问到构造函数原型链中的属性,换句话说通过 new 操作符,实例与构造函数通过原型链连接了起来。
我们接着探索new的作用,现在的TestPersion中没有显示的return任何值(默认为undefined),试着让他返回值试试:
demo4.png
通过这个例子,我们可以得出一个结论:
- 如果构造函数没有返回值或者返回值是非对象,那么返回的就是构造函数实例后的对象(注意:return null,返回的也是构造函数实例后的对象而非null);如果函数return对象,那么返回这个对象。
同时这个例子也告诉我们:
构造函数尽量不要返回值。因为返回原始值不会生效,返回对象会导致 new 操作符没有作用。
new的模拟实现
我们已经知道new的作用了,即当调用new的时候,JavaScript做了什么:
- new 操作符会返回一个对象
- 这个对象,也就是构造函数中的 this,可以访问到挂载在 this 上的任意属性
- 这个对象可以访问到构造函数原型上的属性
-
返回原始值需要忽略,返回对象需要正常处理
下图是MDN中的说法: demo5.png
基于这些作用,我们可以来实现这些功能了
demo6.png
总结下实现方式:
- 首先是创建一个新的空对象
- 因为 newObj对象需要访问构造函数原型链上的属性,所以通过 setPrototypeOf 将两者联系起来。这段代码等同于 newObj.proto = Con.prototype
- 将 newObj绑定到构造函数上,并且传入剩余的参数
- 判断构造函数返回值是否为对象,如果为对象就使用构造函数返回的值,否则使用 newObj,这样就实现了忽略构造函数返回的原始值