js中new操作符具体都干了什么?
在JavaScript中,new
操作符是一个用于创建对象实例的关键字,它背后的机制相当复杂,但以下是它执行的主要步骤:
new
操作符的工作原理:
-
创建一个全新的空对象:首先,JavaScript会创建一个全新的对象,这个对象没有原型(
[[Prototype]]
属性为null
)。 -
将这个空对象的原型设置为构造函数的
prototype
属性:然后,这个新对象的[[Prototype]]
属性会被设置为构造函数的prototype
属性。这意味着新对象可以访问构造函数原型上的所有方法和属性。 -
绑定
this
到新对象:接下来,构造函数被调用,this
关键字被绑定到新创建的对象上。这意味着在构造函数内部声明的所有属性和方法都会成为新对象的属性。 -
执行构造函数的代码:构造函数内部会执行一些代码,可能包括为
this
添加新的属性和方法。 -
返回这个新对象:如果构造函数没有显式地返回一个对象,那么
new
表达式会返回步骤1中创建的新对象。
详细的步骤:
-
步骤 1:
let obj = {};
-
步骤 2:
obj.__proto__ = Constructor.prototype;
-
步骤 3:
Constructor.call(obj, arguments...);
(这里的arguments...
代表构造函数的参数) -
步骤 4:检查构造函数返回的结果:
- 如果构造函数返回了一个对象,那么
new
操作符会返回这个对象。 - 如果构造函数没有返回对象,或者返回的是一个基本数据类型(如数字、字符串、布尔值),那么
new
操作符会返回步骤1中创建的对象。
- 如果构造函数返回了一个对象,那么
示例:
function Person(name, age) {
this.name = name;
this.age = age;
}
var person1 = new Person('Alice', 25);
// person1 是一个新的对象
// person1 的 [[Prototype]] 指向 Person.prototype
// Person.prototype 上的方法如 toString() 可以被 person1 调用
// 构造函数 Person 被调用,this 指向 person1,因此 person1 拥有 name 和 age 属性
在这个例子中,new
操作符创建了person1
对象,将Person.prototype
设置为其原型,并调用Person
构造函数来初始化person1
的属性。如果Person
构造函数返回了一个对象,那么new
操作符会返回这个对象;如果没有返回,它就返回person1
。