在 JavaScript 中,若不直接使用 new 关键字,请通过编写函数来模拟 new 的完整执行流程,并给出具体实现代码。
考察说明
考查对 new 操作符内部机制的理解与手动实现能力。
回答思路
- 【回答框架 1】new 操作符执行时主要完成四步:创建一个新对象,将该对象的原型链接到构造函数的 prototype 属性,以新对象为 this 调用构造函数,若构造函数返回对象则返回该对象,否则返回新对象。
- 【回答框架 2】实现模拟函数时,先创建空对象,可用 Object.create 直接以构造函数的 prototype 作为原型创建,也可先创建空对象再设置 __proto__ 或使用 Object.setPrototypeOf。
- 【回答框架 3】调用构造函数时使用 apply 或 call 传入新对象和参数列表,注意处理构造函数显式返回对象的情况,若返回值为对象(非 null)则返回该值,否则返回第一步创建的新对象。
- 【回答框架 4】具体代码示例:function myNew(fn, ...args) { const obj = Object.create(fn.prototype); const result = fn.apply(obj, args); return (result !== null && (typeof result === 'object' || typeof result === 'function')) ? result : obj; }
- 【关键点 1】new 先创建新对象并链接原型,再以该对象为 this 执行构造函数。
- 【关键点 2】构造函数返回引用类型(对象或函数)时,new 返回该引用类型;返回基本类型或 undefined 时,返回新创建的对象。
- 【关键点 3】模拟实现可用 Object.create 设置原型,用 apply/call 绑定 this 并传参。
- 【关键点 4】注意 null 不是对象,不应作为返回值判定。
- 【关键点 5】扩展性考虑:模拟函数不易处理构造函数没有 prototype 属性的情况(如箭头函数)。
- 【易错点 1】若构造函数显式返回 null,应返回新对象,因为 null 属于基本类型。
- 【易错点 2】使用 obj.__proto__ = fn.prototype 可能因浏览器兼容性不如 Object.create 可靠。
- 【易错点 3】模拟实现无法完全复现 new 对内置构造函数的特殊行为,但满足常规场景。