JavaScript new 的模拟实现
一、什么是 new 操作符
使用过 JavaScript 的朋友一定都使用过 new,new 一个实例出来。然而 new 这个语法糖是个什么过程呢?
首先我们看看 new 操作符是怎么回事:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.code = "007";
let student = new Person("张三", 18);
console.log(student.code); // "007"
console.log(student.name); // "张三"
console.log(student.age); // 18
我们可以看到:
- 创建了一个新的实例对象 student
- new 出来的实例 student 的 __proto__ 指向了 Person.prototype
- 改变了构造函数里的 this 的指向,不在指向 window,而是指向新建的实例 student
嗯,差不多 new 干了这些事。
**就这样完了吗?**我们还需要注意一些细节:
由于构造函数返回的对象就是 new 出来的结果,一般情况下构造函数不返回值,但用户可以选择主动返回对象,当显式返回对象时,就会覆盖掉 new 操作符创建的实例对象,如下:
function Person(name, age) {
this.name = name;
this.age = age;
return {
money: 100
}
}
let student = new Person("张三", 18);
console.log(student);
当显示返回对象时,覆盖实例,不是张三,而是 money。
二、模拟实现 new 操作符
根据上面的 new 操作分析,可以得出以下步骤:
- 创建一个新的空对象
- 将该对象的 __proto__ 指向构造函数的 prototype(可以使用 Object.create(),省略第一步)
- 使用 apply 改变构造函数的 this 的指向,使其指向新建的对象
- 捕获进行 apply 操作后的返回值,查看执行构造函数后返回的是否是显式对象而不是 undefined
- 如果执行构造函数后的返回值是对象,那么返回该对象,否则返回第一步新建的对象
function myNew(constructor, ...args) {
if (typeof constructor !== "function")
return new TypeError(constructor + " is not a constructor");
let obj = Object.create(constructor.prototype);
let result = constructor.apply(obj, args);
return result instanceof Object ? result : obj;
}
喜欢的话记得点个赞再走哦!