1. new
操作符
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。
使用new
调用类的构造函数会执行如下操作:
1 | ⭐ 1.构造函数无返回值 |
所以说new
操作符必须要返回一个对象,如果构造函数中没有return
那就返回this
,如果有return
并且return
的是一个对象,那么就会返回这个对象,否则都返回this
。
来自MDN的解释:
当代码new Foo(...)
执行时,会发生以下事情:
1.一个继承自Foo.prototype
的新对象被创建。
2.使用指定的参数调用构造函数Foo
,并将this
绑定到新创建的对象。new Foo
等同于new Foo()
,也就是没有指定参数列表,Foo
不带任何参数调用的情况。
3.由构造函数返回的对象就是new
表达式的结果。如果构造函数没有显式返回一个对象,则使用步骤1创建的对象。(一般情况下,构造函数不返回值,但是用户可以选择主动返回对象,来覆盖正常的对象创建步骤)
※ 构造函数为箭头函数
普通函数创建时,引擎会按照特定的规则为这个函数创建一个prototype
属性(指向原型对象)。默认情况下,所有原型对象自动获得一个名为 constructor
的属性,指回与之关联的构造函数。
1 | function Person(){ |
创建箭头函数时,引擎不会为其创建prototype
属性,箭头函数没有constructor
供new
调用,因此使用new调用箭头函数会报错!
1 | const Person = ()=>{} |
也就是说构造函数必须是声明式的,即function xxx()
,不可以是表达式的。
2.手写new
依据原理:
- 创建一个对象
obj
- 该对象的
__proto__
指向构造函数Fn的原型prototype
- 执行构造函数
Fn
的代码,往新创建的对象obj
上添加成员属性和方法 - 返回这个新的对象
obj
1 | function _new (constructor, ...args) { |
Object.create
作用:创建一个新对象,使用现有的对象来提供新创建的对象的 __proto__
因此,可以得出结论
1 | let obj = Object.create(func.prototype) |
通过new
的方式创建对象与通过字面量创建的区别
new Object()
方式创建对象本质上是方法调用,涉及到在原型链中查找该方法,当找到该方法后,又会生产方法调用必须的堆栈信息,方法调用结束后,还要释放该堆栈,性能不如字面量的方式- 通过对象字面量定义对象时,不会调用
Object
的构造函数
Tips : 使用字面量的方式创建对象 性能上 更好,可读性 更高