js的new操作符
我们先来了解一下new运算符的基本概念:
new运算符创建一个用户自定义的对象类型的实例或具有构造函数的内置对象的实例。new关键字会进行如下操作:
- 先创建一个新的空的简单JavaScript对象(即
{}) - 然后让这个空对象的
_proto_指向函数的原型prototype - 将步骤1创建的对象作为
this的上下文(将对象作为函数的this传进去) - 如果该函数没有返回对象,则返回
this
再来看一段代码:
1 | function Person(name){ |
可以看到,有new和没new的区别所在,现在分析一下new做了什么
当代码new Person(...)执行时,会发生以下事情:
- 一个继承自
Person.prototype的新对象被创建 - 使用参数
Tom调用构造函数Person,并将this绑定到新创建的对象。 - 由构造函数
Person返回的对象就是new表达式的结果(即构造函数实例化后的对象)。
那要是构造函数返回的是一个对象呢?
1 | function Person(name){ |
可以看到,当函数返回的是对象时,则返回的即为该对象。
可是,当构造函数返回null,undefined等非对象时,情况又是什么样的?
1 | function Person(name){ |
可以看到,return null时(当使用new操作符)返回的也是构造函数实例后的对象。这是因为null、undefined为非对象,所以return的其实为this
那,要是没有return语句呢?
1 | function Person(name) { |
其实,如果在JavaScript没有return语句,那么函数就会默认return this
所以,我们可以得出结论:当我们使用了new操作符时,①构造函数如果没有返回对象,那么这个返回值毫无意义;②构造函数如果返回值为对象,那么这个返回值会被正常使用
接下来,我们再看一个例子:
1 | function Person(name){ |
从这里,我们可以看出new操作符的一些作用:
new通过构造函数Person创建出来的实例可以访问到构造函数中的属性new通过构造函数Person创建出来的实例可以访问到构造函数原型链中的属性,也就是说通过 new 操作符,实例与构造函数通过原型链连接了起来
最后,我们可以自己尝试模拟实现new运算符
1 | function create() { //(Con, ...args)函数接收不定量的参数,第一个参数为构造函数,接下来的参数被构造函数使用 |
参考资料: