news 2026/4/13 6:24:15

深入理解 JavaScript 中的 `new` 运算符与类数组 `arguments`

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入理解 JavaScript 中的 `new` 运算符与类数组 `arguments`

在 JavaScript 的面向对象编程中,new运算符扮演着至关重要的角色。它不仅用于创建构造函数的实例,还隐式地完成了
原型链的建立、this绑定等关键操作。与此同时,JavaScript 函数调用时会自动提供一个特殊的“类数组”对象——arguments,它虽然具有类似数组的结构,却不能直接使用数组的方法。本文将深入剖析new运算符的内部机制,并通过手写实现的方式加深理解;同时探讨arguments对象的本质及其转换为真实数组的方法。

一、new运算符的本质:从空对象到实例

当我们使用new Person('张三', 18)创建一个对象时,JavaScript 引擎实际上执行了以下四个步骤:

  1. 创建一个全新的空对象
    这个对象没有任何自有属性,但它是后续所有操作的基础。
  2. 将构造函数中的this指向这个新对象
    构造函数内部通过this.name = name等语句为新对象添加属性。
  3. 设置新对象的__proto__属性,使其指向构造函数的prototype
    这一步建立了原型链,使得新对象可以访问构造函数原型上的方法和属性(如Person.prototype.sayHi)。
  4. 返回新对象
    如果构造函数没有显式返回一个对象,则默认返回这个新创建的对象。

这四个步骤构成了 JavaScript 基于原型的面向对象模型的核心。

二、手写new:模拟实例化过程

为了更直观地理解上述机制,我们可以手动实现一个objectFactory函数,模拟new的行为:

function objectFactory() { // 1. 创建一个空对象 var obj = new Object(); // 2. 取出第一个参数作为构造函数 var Constructor = [].shift.call(arguments); // 3. 将构造函数的this 绑定到新对象,并传入剩余参数Constructor.apply(obj, arguments); // 4. 设置原型链 obj.__proto__ = Constructor.prototype; // 5. 返回新对象 return obj; }

代码解析

  • [].shift.call(arguments):由于arguments是类数组,不能直接调用数组方法,但可以通过Array.prototype.shift.call来“借用”方法,取出第一个参数(即构造函数),同时arguments自动更新为剩余参数。
  • Constructor.apply(obj, arguments):将构造函数的执行上下文绑定到obj,并传入参数,完成属性赋值。
  • obj.__proto__ = Constructor.prototype:手动建立原型链,使obj能继承Constructor.prototype上的方法。

测试验证

function Person(name, age) { this.name = name; this.age = age; } Person.prototype.species = '人类'; Person.prototype.sayHi = function() { console.log(`你好,我是${this.name}`); }; let p = new Person('张三', 18); let zzp = objectFactory(Person, '郑志鹏', 18); console.log(zzp.age); // 18 console.log(zzp.species); // '人类' zzp.sayHi(); // "你好,我是郑志鹏"

结果表明,objectFactory成功复现了new的全部功能。

注意:现代 JavaScript 更推荐使用 Object.create
(Constructor.prototype)来创建对象,以避免直接操作__proto__(该属性已不推荐使用)。但在教学和理解层面,上述写法清晰展示了原型链的建立过程。

三、类数组arguments:函数的隐式参数容器

在非箭头函数中,JavaScript 会自动提供一个名为arguments的局部变量。它是一个类数组对象(array-like object),具有以下特征:

  • 拥有length属性;
  • 可通过数字索引(如arguments[0])访问参数;
  • 不具备数组的内置方法,如mapreducejoin等;
  • [[Prototype]]指向Object.prototype,而非Array.prototype

为什么arguments不是真正的数组?

尽管arguments看起来像数组,但它本质上是一个普通对象:

function test() { console.log(Object.prototype.toString.call(arguments)); // "[object Arguments]" console.log(arguments instanceof Array); // false } test(1, 2, 3);

因此,直接调用arguments.reduce(...)会报错。

四、将arguments转换为真实数组

要让arguments使用数组方法,必须将其转换为真正的数组。常用方法包括:

1. 扩展运算符
(ES6+)

const args = [...arguments];

2.Array.from()

const args = Array.from(arguments);

3. 借用数组的slice方法

const args = [].slice.call(arguments); // 或 const args = Array.prototype.slice.call(arguments);

实际应用示例

假设我们要实现一个可接受任意数量参数的求和函数:

function add() { const args = [...arguments]; return args.reduce((prev, cur) => prev + cur, 0); } console.log(add(1, 2)); // 3 console.log(add(1, 2, 3, 4)); // 10

这种方式既简洁又安全,充分利用了现代 JavaScript 的特性。

五、总结与思考

通过手写new运算符的实现,我们深入理解了 JavaScript 面向对象的核心机制:对象创建、this绑定、原型链继承。这不仅是面试中的高频考点,更是掌握 JS 底层逻辑的关键。

而对arguments的探讨则揭示了 JavaScript 动态参数处理的灵活性与局限性。虽然 ES6 引入了剩余参数(rest parameters)(如function add(...args)),使得arguments的使用逐渐减少,但在阅读旧代码或处理特殊场景时,理解arguments依然不可或缺。

最佳实践建议

  • 在新项目中优先使用...args替代arguments
  • 避免直接操作__proto__,改用Object.create()
  • 理解原型链和this绑定,是写出健壮 JS 代码的基础。

JavaScript 的魅力在于其看似简单却深藏玄机的机制。只有透过表象,深入底层,才能真正驾驭这门语言。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 2:50:25

VSCode调试量子机器学习模型,90%的人都忽略的5个关键断点设置

第一章:VSCode调试量子机器学习模型的核心价值在量子计算与人工智能深度融合的当下,量子机器学习(QML)正逐步从理论走向实践。VSCode 作为现代开发者的首选编辑器,凭借其强大的扩展生态和调试能力,成为构建…

作者头像 李华
网站建设 2026/4/12 11:41:49

如何为STM32微控制器配置SD NAND存储驱动

如何为STM32微控制器配置SD NAND存储驱动 【免费下载链接】MK米客方德SDNAND的STM32驱动例程 该项目提供了一个针对STM32微控制器与SD NAND存储器的驱动例程,帮助开发者快速实现两者之间的通信与集成。例程涵盖了初始化、数据读写及错误处理等关键步骤,适…

作者头像 李华
网站建设 2026/4/6 16:52:35

如何5分钟快速配置NI-VISA:虚拟仪器通信终极指南

如何5分钟快速配置NI-VISA:虚拟仪器通信终极指南 【免费下载链接】NI-VISA下载安装使用指南 NI-VISA(Virtual Instrument Software Architecture)是用于控制和通信的标准API,广泛应用于LabVIEW等虚拟仪器软件中。本资源文件提供了…

作者头像 李华
网站建设 2026/4/5 18:37:05

pg_replicate终极指南:5分钟掌握PostgreSQL数据复制的Rust实战教程

pg_replicate终极指南:5分钟掌握PostgreSQL数据复制的Rust实战教程 【免费下载链接】pg_replicate Build Postgres replication apps in Rust 项目地址: https://gitcode.com/gh_mirrors/pg/pg_replicate 在当今数据驱动的时代,实时数据复制已成为…

作者头像 李华
网站建设 2026/4/12 8:32:19

CLIP模型微调--附训练代码

文章目录 CLIP模型微调方法 代码示例(PyTorch) 注意事项 CLIP模型微调方法 CLIP(Contrastive Language-Image Pretraining)是OpenAI提出的多模态模型,通过对比学习将图像和文本嵌入到同一空间。微调CLIP可适应特定任务,以下是关键步骤: 准备数据集 构建包含图像-文本对…

作者头像 李华
网站建设 2026/4/7 20:08:59

程序员如何高效对接微信个人号API接口进行二次开发

您是否正在为您的业务或项目寻求一个强大、高效、稳定的微信集成解决方案?您是否厌倦了直接与复杂的微信开放平台 API 打交道,花费大量时间在基础配置和签名校验上? 现在,是时候升级您的开发体验了! 隆重推出 GeWe 框…

作者头像 李华