new操作符创建对象时会连接原型、绑定this并返回实例;通过myNew函数可模拟该过程:创建空对象并继承构造函数原型,调用构造函数并将this指向新对象,若返回值为对象则返回该值,否则返回新对象。

在JavaScript中,new 操作符用于创建一个用户自定义对象类型的实例或具有构造函数的内置对象类型的实例。理解并模拟实现 new 操作符,有助于深入掌握 JavaScript 的面向对象机制和原型链原理。
new 操作符到底做了什么?
当我们使用 new constructor() 时,JavaScript 引擎内部会执行以下步骤:
- 创建一个全新的空对象;
- 将这个新对象的隐式原型(__proto__)指向构造函数的 prototype 属性;
- 将构造函数中的 this 绑定到这个新对象上,并执行构造函数体内的代码;
- 如果构造函数返回了一个非原始类型(即对象或函数),则返回这个返回值;否则返回新创建的对象。
手动模拟实现 myNew 函数
基于上述行为,我们可以写一个函数 myNew 来模拟 new 的效果:
function myNew(constructor, …args) { // 1. 创建一个空对象,继承构造函数的 prototype const obj = Object.create(Constructor.prototype); // 2. 调用构造函数,this 指向新对象 const result = Constructor.apply(obj, args); // 3. 如果构造函数返回对象,则使用该返回值,否则返回新对象 return result instanceof Object ? result : obj; }
测试我们的模拟实现
来看一个实际例子:
立即学习“Java免费学习笔记(深入)”;
function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`Hello, I’m ${this.name}`); }; // 使用原生 new const p1 = new Person(“Alice”, 25); p1.sayHello(); // 输出: Hello, I’m Alice // 使用我们实现的 myNew const p2 = myNew(Person, “Bob”, 30); p2.sayHello(); // 输出: Hello, I’m Bob console.log(p1 instanceof Person); // true console.log(p2 instanceof Person); // true
可以看到,p2 和 p1 表现一致,说明我们的模拟基本成功。
处理构造函数返回对象的情况
有些构造函数可能会显式返回一个对象,这时候 new 应该忽略之前创建的实例。例如:
function Special() { this.value = ‘ignored‘; return { custom: ‘object’ }; } console.log(new Special()); // { custom: ‘object’ } console.log(myNew(Special)); // 同样输出 { custom: ‘object’ }
这验证了我们在 myNew 中对返回值的判断是必要的。
基本上就这些。不复杂但容易忽略细节。
以上就是JS中如何模拟实现


