如何编写函数复刻JavaScript new运算符功能?自定义myNew函数排障
复刻JavaScript中new运算符功能的实现方案及问题排查
- 如何编写一个能够复刻JavaScript中new运算符功能的函数?
- 我尝试用myNew函数模拟new运算符,但始终无法正常运行,以下是我的实现代码:
function Person(name) { this.name = name; } Person.prototype.getName = function() { return this.name; } function myNew(){ var obj = Object.create(Object.prototype); var instance = this.apply(obj, arguments); return instance; } var person = myNew(Person, 'Test'); console.log(person instanceof Person); // true person.getName(); // Test请帮忙排查问题并给出正确的实现方案。
你的代码存在的核心问题
咱们先拆解下你实现里的几个关键错误:
this指向完全错误:当你直接调用myNew()时,函数内部的this在非严格模式下指向全局对象(浏览器里是window),严格模式下是undefined,根本没指向你传入的Person构造函数。所以this.apply(obj, arguments)这行代码完全没调用到Person,逻辑彻底跑偏了。- 原型链未正确关联:你创建的
obj原型是Object.prototype,但new运算符创建的实例原型应该指向构造函数的prototype,这样实例才能继承构造函数原型上的方法(比如getName)。 - 返回值处理错误:构造函数如果没有返回对象类型的值(比如
Person没有return),new应该返回我们创建的新对象,但你的代码直接返回instance(也就是this.apply的结果,这里实际是undefined),最终person会是undefined,调用person.getName()必然报错。
正确的new运算符模拟实现
要复刻new的功能,我们得严格遵循它的执行逻辑:
- 创建一个新对象,其原型指向构造函数的
prototype - 将构造函数的
this绑定到这个新对象,传入剩余参数执行构造函数 - 判断构造函数的返回值:如果是对象类型(且不是
null),则返回这个对象;否则返回我们创建的新对象
下面是完整的正确实现:
function Person(name) { this.name = name; } Person.prototype.getName = function() { return this.name; } function myNew(constructor, ...args) { // 1. 创建新对象,原型指向构造函数的prototype const obj = Object.create(constructor.prototype); // 2. 绑定this到新对象,执行构造函数 const result = constructor.apply(obj, args); // 3. 判断返回值:如果是对象(非null)则返回它,否则返回新对象 return typeof result === 'object' && result !== null ? result : obj; } // 测试 var person = myNew(Person, 'Test'); console.log(person instanceof Person); // true console.log(person.getName()); // Test
兼容ES5的版本(如果不能用扩展运算符)
如果需要兼容不支持ES6扩展运算符的环境,可以这样处理参数:
function myNew() { // 取出第一个参数作为构造函数 var constructor = Array.prototype.shift.call(arguments); // 创建新对象 var obj = Object.create(constructor.prototype); // 执行构造函数 var result = constructor.apply(obj, arguments); // 返回处理 return typeof result === 'object' && result !== null ? result : obj; }
这样就能完美复刻new运算符的所有核心功能啦!
内容的提问来源于stack exchange,提问作者Panbok
相关产品推荐
相关产品推荐

