同系列文章请查看:Github:pre-interview
new一个构造函数过程中发生了什么
红宝书:
要创建 Person 的实例,应使用 new 操作符。以这种方式调用 构造函数 会执行如下操作:
(1) 在内存中创建一个新对象
(2) 这个新对象内部的 [ [Prototype] ] 特性被赋值为构造函数的 prototype属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
在创建一个实例对象的时候 new关键字都起到了哪些作用呢?
在没有学习原型之前 我们可以这么给出定义——
- 创建一个 类(或者模拟类 比如说构造函数)的实例对象
之前学Java面向对象的时候 并没有在这里想太多 就是知道 new一个对象嘛~创建出来的实例对象继承了父类的所有属性与方法 就这些🤔
那么在JavaScript中 情况有些不同,尤其是学过原型之后 我们知道 JS中的new关键字还背负着一些使命。
这里涉及了原型、this指向、作用域、函数return的知识。
举个例子来把内容串起来:
1 | function Person(name, age){ |
用伪代码模拟下上述过程的执行过程:
1 | var person = new Person("bill",21); |
1 | new Person('bill',21) = { |
关于步骤04,详见 构造函数的返回值
来拆分开看看
1)创建了一个新的空对象 {}
1 | var person = {}; |
2)将新对象的 __proto__
指向构造函数的 prototype
属性
- 也就是设置这个对象原型指向构造函数
1 | person.__proto__ = Person.prototype; |
这里还可以像下面一样写,效果相同的。
1 | person.__proto__ = Object.create(Person.prototype); |
3)将构造函数的作用域赋值给新对象(this指向新创建的对象实例person)
这里注意
Person.call(person, args)
会为这个新对象person添加属性(同时this会指向新创建的对象)另外返回值res为构造函数的返回值(因为这个过程相当于调用构造函数~)
1 | var res = Person.call(person, 'bill', 21); |
4)返回新对象(这里注意 如果构造函数中return一个对象 那么会返回return的内容 而不是创建的这个对象)
1 | return res; |
截至此处 new关键字的工作就完成了
关于 new 的必需的前置知识:原型链
Tips: Please indicate the source and original author when reprinting or quoting this article.