参透 JavaScript —— 彻底理解 new 操作符及手写实现

前言

本篇文章主要理解 new 操作符的原理,并手写实现一个自己的 "new"

new 操作符在背后做了什么?

在上篇文章中讲解了原型与原型链,讲到了使用 new 操作符创建实例对象

  1. 为什么 new 操作符创建的对象会拥有构造函数上的全部属性和方法?
  2. 为什么实例对象上的原型指针会指向构造函数的原型?

要明白这些问题,就要知道 new 操作符在实例化时做了什么

翻开《JavaScript 高级程序设计》第四版中关于原型的篇章,当以 new 关键字调用函数时,会执行以下操作:

  1. 在内存中创建一个新对象
  2. 这个新对象内部的 [[Prototype]] 特性被赋值为构造函数的 prototyoe 属性
  3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
  4. 执行构造函数内部的代码(给新对象添加属性)
  5. 如果构造函数返回非空对象,返回这个对象;否则,返回新创建的对象

手写自己的 new 操作符

按照上面流程,我们可以模拟写一个自己的 new

比如,我们拥有一个 myNew 函数

js 复制代码
function myNew(constructor, ...args) {
  // 1.在内存中创建一个新对象
  // 2.这个新对象内部的 `[[Prototype]]` 特性被赋值为构造函数的 prototyoe 属性
  const obj = Object.create(constructor.prototype);

  // 3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
  // 4. 执行构造函数内部的代码(给新对象添加属性)
  const result = constructor.apply(obj, args);

  // 5. 如果构造函数返回非空对象,返回这个对象;否则,返回新创建的对象
  return (result !== null && typeof result === 'object') ? result : obj;
}

解析:

使用 Object.create 来实现第一步、第二步,这个方法会创建一个新对象,并且将新对象的原型指针指向传入的对象的原型

在第三步和第四步,使用了函数上的实例方法 Function.protytype.apply

这个方法会改变函数内部的 this 指向,并且将剩余的参数(arguments)作为数组传入,然后调用该函数

手写的效果

在谷歌浏览器 - F12 开发者工具上测试效果

总结

实例对象拥有构造函数的全部属性和方法,并且原型指针指向构造函数的原型,都是 new 操作符在背后做的工作:

  1. 在内存中创建一个新对象
  2. 这个新对象内部的 [[Prototype]] 特性被赋值为构造函数的 prototyoe 属性
  3. 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)
  4. 执行构造函数内部的代码(给新对象添加属性)
  5. 如果构造函数返回非空对象,返回这个对象;否则,返回新创建的对象

记住,手写实现 new 操作符,本质是为了实践理解 new 操作符的背后原理

参考资料

参透JavaScript系列

本文已收录至《参透 JavaScript 系列》,全文地址:我的 GitHub 博客 | 掘金专栏

交流讨论

对文章内容有任何疑问、建议,或发现有错误,欢迎交流和指正

相关推荐
研☆香5 分钟前
js中使用的正则表达式
开发语言·javascript·正则表达式
szarron5 分钟前
国产手持式频谱分析仪选型攻略:TFN RC系列 vs HTOOL SA8T频谱分析仪 专业参数对比(军工/路测/调试全覆盖)
开发语言·前端·状态模式
开开心心就好13 分钟前
免费桌签打印工具,支持批量导入名字
前端·javascript·人工智能·docker·jupyter·智能手机·语音识别
涛涛ing14 分钟前
2026 年 9 月,整个 npm 生态的「心脏」都被 Rust 换了
前端
IT_陈寒18 分钟前
明明设了默认值,为什么我的JavaScript函数参数还是undefined?
前端·人工智能·后端
CappuccinoRose19 分钟前
Web Components 基础
前端·javascript·交互·web component·shadow dom
晴天1621 分钟前
前端 Monorepo 入门分享:从概念到实践
前端
imgsq24 分钟前
MapLibre GL JS v6 正式发布:v5 之后八个月的第一个大版本(编译)
开发语言·javascript·ecmascript
lytao12336 分钟前
90% 覆盖率不等于没 Bug:用风险配置测试组合
前端·javascript·bug·软件工程
mayaairi40 分钟前
Vue2 组件通讯(一):Props传值完全指南
前端·javascript·vue.js