【前端】JavaScript 中 arguments、类数组与数组的深入解析
文章目录
- 💯前言
- 💯什么是 `arguments` 对象
- 2.1 `arguments` 的定义
- 2.2 `arguments` 的特性
- 2.3 使用场景
- 💯深入了解 `arguments` 的结构
- 3.1 `arguments` 的内部结构
- `arguments` 的关键属性
- 3.2 类数组 VS 真正的数组
- 什么是类数组?
- 类数组和数组的主要区别
- 💯如何将类数组转换为数组?
- 4.1 使用 `Array.from`
- 4.2 使用扩展运算符(`...`)
- 4.3 使用 `Array.prototype.slice`
- 💯箭头函数与 `arguments`
- 💯现代 JavaScript 中的替代方案:剩余参数
- 6.1 剩余参数语法
- 6.2 优势
- 💯总结与最佳实践
- 7.1 使用场景建议
- 7.2 转换类数组的首选方法
- 7.3 常见误区
- 💯小结
💯前言
- JavaScript 是一种灵活多变的编程语言,其中有一个特别的对象叫作
arguments
,在非箭头函数中非常有用。它是一个类数组对象,用于捕获调用时的所有参数。本文将从实际使用的角度,详细分析arguments
对象、类数组和数组的区别,并通过示例
讲解如何在应用中高效地使用这些特性。理解arguments
对象和类数组的概念对 JavaScript 开发者来说至关重要,因为这可以帮助更灵活地处理函数传参问题,从而编写出更加健壮和简洁的代码。
JavaScript
💯什么是 arguments
对象
arguments
是一个特殊的对象,在非箭头函数的作用域中自动生成。它是 JavaScript 用来捕获调用函数时传递的所有参数的一个机制。
2.1 arguments
的定义
arguments
是一个类数组对象,包含了调用函数时传递给函数的所有参数的值。它在函数调用时自动生成,无需手动声明。通过arguments
,我们可以访问到函数传递的所有参数,即使这些参数没有在函数的形参列表中明确定义。这种特性在处理未知数量参数时非常有用,尤其是在 JavaScript 的早期版本中,arguments
是唯一的办法来处理可变数量的参数。
示例:
function example() {console.log(arguments); // 输出 arguments 对象
}example(1, 2, 3);
// 控制台输出:
// [Arguments] { '0': 1, '1': 2, '2': 3 }
2.2 arguments
的特性
- 类数组:
arguments
具有length
属性,用于表示参数的数量,可以通过索引访问每个参数值。虽然它看起来像一个数组,但实际上它是一个对象。 - 只读属性:在大多数环境中,
arguments
的值是只读的,不能随意修改,否则可能会导致不可预期的行为。 - 不是真正的数组:它虽然看起来像数组,但并不是真正的数组,无法直接使用数组的方法(例如
push
、map
等)。如果需要使用这些方法,我们通常需要将arguments
转换为真正的数组。 - 存在于普通函数中:
arguments
仅在普通函数中有效,在箭头函数中不存在。这是因为箭头函数没有自己的arguments
对象,它们会从包含它们的父级作用域中继承arguments
。 - 性能警告:在现代 JavaScript 中,
arguments
对象已经逐渐被剩余参数语法(...rest
)取代,因为后者更加高效和直观。尤其是在涉及到复杂操作和高性能需求的情况下,剩余参数的表现通常要优于arguments
。
2.3 使用场景
arguments
在以下情况下非常有用:
-
处理未知数量的参数:
在不知道函数调用时会传入多少个参数的情况下,arguments
提供了一种方法来动态访问所有参数。这在构建通用工具函数或处理多个输入值时非常有帮助。
示例:
function sum() {let total = 0;for (let i = 0; i < arguments.length; i++) {total += arguments[i];}return total; }console.log(sum(1, 2, 3, 4)); // 输出 10
-
实现灵活的参数接口:
在没有使用 ES6 剩余参数语法的旧代码中,arguments
是处理灵活参数的主要工具。这些代码通常需要处理不固定数量的参数,并且不方便直接修改函数定义,此时arguments
显得尤为重要。 -
函数重载实现:
在一些场景下,可能会需要根据传入参数的不同类型或数量来执行不同的逻辑。虽然 JavaScript 没有原生的函数重载,但可以通过arguments
对象来模拟这种效果。
示例:
function example() {if (arguments.length === 0) {console.log('没有传入参数');} else {console.log('传入了', arguments.length, '个参数');} }example(); // 输出: 没有传入参数 example(1, 2); // 输出: 传入了 2 个参数
💯深入了解 arguments
的结构
3.1 arguments
的内部结构
- 在控制台中打印
arguments
对象,会发现它是一个带有特殊属性的对象:
function test() {console.log(arguments);
}test(1, 2, 3);
// 输出:
/*
Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
*/
arguments
的关键属性
- 索引属性:
- 存储每个参数值,可以通过
arguments[0]
访问第一个参数,arguments[1]
访问第二个参数,以此类推。
- 存储每个参数值,可以通过
length
属性:- 表示传入的参数数量,方便我们对参数进行遍历。
callee
属性:- 指向当前函数本身(严格模式下禁用),在某些场景下可能会用来递归调用。
Symbol.iterator
属性:- 允许使用
for...of
循环进行遍历arguments
对象。这使得arguments
可以像数组一样被迭代,尽管它不是真正的数组。
- 允许使用
3.2 类数组 VS 真正的数组
什么是类数组?
类数组是一个具有类似数组结构的对象,它满足以下条件:
- 拥有按索引存储的数据。
- 拥有
length
属性。 - 不能直接使用数组的原型方法(例如
push
、map
等)。
类数组对象是广泛存在于 JavaScript 中的数据结构,常见的类数组对象包括:
常见的类数组对象:
arguments
对象:捕获函数调用时传入的所有参数。NodeList
(Document Object Model 操作中的节点列表,用于包含由选择器或其他查询方法返回的元素集合)。HTMLCollection
(通过getElementsByClassName
返回的集合)。
类数组和数组的主要区别
特性 | 类数组 | 数组 |
---|---|---|
类型 | Object | Array |
检测方式 | typeof 返回 object | Array.isArray() 返回 true |
原型方法 | 无法直接使用数组方法 | 可以使用数组方法 |
转换为数组的方式 | 需要手动转换 | 无需转换 |
遍历方式 | 可通过索引访问 | 支持所有数组遍历方法 |
类数组对象通常需要经过转换才能使用数组的方法。尽管它们在某些情况下具有数组的特性,但直接调用如 map()
或 forEach()
这样的数组方法会导致错误,因为它们并不继承自 Array
的原型链。
💯如何将类数组转换为数组?
在实际开发中,类数组常常需要转换为真正的数组以使用数组的强大功能。以下是常用的转换方法:
4.1 使用 Array.from
Array.from
是一个将类数组或可迭代对象转换为数组的内置方法。
function test() {const args = Array.from(arguments);console.log(args.map(x => x * 2)); // [2, 4, 6]
}test(1, 2, 3);
4.2 使用扩展运算符(...
)
- 扩展运算符是 ES6 引入的功能,可以快速地将类数组展开为数组。
function test() {const args = [...arguments];console.log(args.map(x => x * 2)); // [2, 4, 6]
}test(1, 2, 3);
4.3 使用 Array.prototype.slice
- 在 ES5 中,
slice
方法常用于将类数组转换为数组。
function test() {const args = Array.prototype.slice.call(arguments);console.log(args.map(x => x * 2)); // [2, 4, 6]
}test(1, 2, 3);
这些方法的核心目的是将类数组对象转换为一个真正的数组,以便我们能够使用数组的各种方法(如 map
、filter
等),从而更方便地进行数据操作。
💯箭头函数与 arguments
- 在箭头函数中,
arguments
对象不存在。如果需要捕获参数,必须使用剩余参数。
const example = (...args) => {console.log(args); // [1, 2, 3]
};example(1, 2, 3);
箭头函数没有自己的 arguments
对象,因为它们的作用域继承自包含它们的上下文。这种特性使得箭头函数更适合在保持作用域一致的回调函数中使用。
💯现代 JavaScript 中的替代方案:剩余参数
6.1 剩余参数语法
- 剩余参数允许将不确定数量的参数捕获为数组。
function sum(...args) {return args.reduce((total, current) => total + current, 0);
}console.log(sum(1, 2, 3, 4)); // 输出 10
剩余参数的引入大大简化了函数参数的处理,因为它能够将所有的传入参数收集到一个数组中,避免了手动转换类数组的繁琐操作。
6.2 优势
- 返回真正的数组:
- 不需要额外的转换操作。
- 简洁明亮:
- 代码更加直观和易读。
- 更好的可维护性:
- 剩余参数的代码结构更简洁、逻辑更清晰,便于团队协作和代码审查。
💯总结与最佳实践
7.1 使用场景建议
- 如果需要兼容旧版 JavaScript,且需要访问所有参数,仍可以使用
arguments
。 - 在现代开发中,优先使用剩余参数替代
arguments
,以简化代码逻辑。剩余参数的灵活性使其能够适应更多的场景,尤其是在函数需要处理可变数量参数时表现更优。
7.2 转换类数组的首选方法
- 使用
Array.from
或扩展运算符(...
)来将类数组对象转换为数组。这些方法能够更高效、更直观地完成转换,并且代码的可读性更好。
7.3 常见误区
-
误以为
arguments
是数组:- 需要明确
arguments
是类数组,而非真正的数组。 - 若直接调用数组方法会导致报错。例如,尝试对
arguments
调用map()
方法会导致TypeError
。
- 需要明确
-
在箭头函数中使用
arguments
:- 箭头函数不支持
arguments
,需要通过剩余参数捕获参数。因为箭头函数的this
和作用域继承自父级上下文,它们不生成自己的arguments
对象。
- 箭头函数不支持
💯小结
通过这篇文章,我们深入探讨了 JavaScript 中arguments
对象的定义、特性、应用场景,以及类数组与数组的区别,并结合现代语法如剩余参数对其进行了优化替代
的说明。理解这些内容将帮助我们在日常开发中更高效地处理函数参数问题,同时编写出更简洁、易于维护的代码。随着 JavaScript 生态系统的不断演进,掌握这些特性不仅能提升开发效率,还能让我们编写出更具现代化风格、更符合最佳实践的代码
。
相关文章:
【前端】JavaScript 中 arguments、类数组与数组的深入解析
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯什么是 arguments 对象2.1 arguments 的定义2.2 arguments 的特性2.3 使用场景 💯深入了解 arguments 的结构3.1 arguments 的内部结构arguments 的关键属性…...
Android 布局菜单或按钮图标或Menu/Item设置可见和不可见
设置可见和不可见 即 设置 显示和隐藏;是双向设置;什么情况显示,什么情况隐藏分判断的条件 它不同于删除和屏蔽,删除和屏蔽,覆盖是单向的,不可逆转的。它间接等于单向的隐藏!!&…...
|| 与 ??的区别
?? : 空值合并运算符, 用于在左侧操作数为 null 或 undefined 时返回右侧操作数 let name null // null 或者 undefinedlet defaultName defaultNamelet displayName name ?? defaultNameconsole.log(displayName) // defaultName || : 逻辑或,…...
wordpress获取文章总数、分类总数、tag总数等
在制作wordpress模板的时候会要调用网站的文章总数分类总数tag总数等这个数值,如果直接用count查询数据库那就太过分了。好在wordpress内置了一些标签可以直接获取到这些数值,本文整理了一些常用的wordpress网站总数标签。 文章总数 <?php $count_…...
pytest 通过实例讲清单元测试、集成测试、测试覆盖率
1. 单元测试 概念 定义: 单元测试是对代码中最小功能单元的测试,通常是函数或类的方法。目标: 验证单个功能是否按照预期工作,而不依赖其他模块或外部资源。特点: 快速、独立,通常是开发者最先编写的测试。 示例:pytest 实现单…...
C#里怎么样自己实现10进制转换为二进制?
C#里怎么样自己实现10进制转换为二进制? 很多情况下,我们都是采用C#里类库来格式化输出二进制数。 如果有人要你自己手写一个10进制数转换为二进制数,并格式化输出, 就可以采用本文里的方法。 这里采用求模和除法来实现的。 下…...
Kafka-Consumer理论知识
一、上下文 之前的博客我们分析了Kafka的设计思想、Kafka的Producer端、Kafka的Server端的分析,为了完整性,我们接下来分析下Kafka的Consumer。《Kafka-代码示例》中有对应的Consumer示例代码,我们以它为入口进行分析 二、KafkaConsumer是什…...
Js-对象-04-Array
重点关注:Array String JSON BOM DOM Array Array对象时用来定义数组的。常用语法格式有如下2种: 方式1: var 变量名 new Array(元素列表); 例如: var arr new Array(1,2,3,4); //1,2,3,4 是存储在数组中的数据࿰…...
React 第八节组件生命周期钩子-类式组件,函数式组件模拟生命周期用法
概述 React组件的生命周期可以分为三个主要阶段: 挂载阶段(Mounting):组件被创建,插入到DOM 树的过程; 更新阶段(Updating):是组件中 props 以及state 发生变化时&#…...
Dubbo源码解析-服务调用(七)
一、服务调用流程 服务在订阅过程中,把notify 过来的urls 都转成了invoker,不知道大家是否还记得前面的rpc 过程,protocol也是在服务端和消费端各连接子一个invoker,如下图: 这张图主要展示rpc 主流程,消费…...
svn 崩溃、 cleanup失败 怎么办
在使用svn的过程中,可能出现整个svn崩溃, 例如cleanup 失败的情况,类似于 这时可以下载本贴资源文件并解压。 或者直接访问网站 SQLite Download Page 进行下载 解压后得到 sqlite3.exe 放到发生问题的svn根目录的.svn路径下 右键呼出pow…...
【Linux系列】NTP时间同步服务器搭建完整指南
在分布式系统和高可用环境中,时间同步是至关重要的。特别是对于银行、金融等关键业务系统,精准的时间同步不仅关系到系统的稳定性,还直接影响交易处理、日志管理、日终结算等功能。本文将介绍NTP(Network Time Protocol࿰…...
go 结构体方法
在 Go 语言中,结构体方法是指附加到结构体类型上的函数。这些方法可以通过结构体的实例来调用。方法的接收者(receiver)指定了该方法属于哪个结构体类型。接收者可以是一个值类型或指针类型。 定义结构体方法 下面是如何为一个结构体定义方…...
DHCP服务(包含配置过程)
目录 一、 DHCP的定义 二、 使用DHCP的好处 三、 DHCP的分配方式 四、 DHCP的租约过程 1. 客户机请求IP 2. 服务器响应 3. 客户机选择IP 4. 服务器确定租约 5. 重新登录 6. 更新租约 五、 DHCP服务配置过程 一、 DHCP的定义 DHCP(Dynamic Host Configur…...
uniapp内嵌的webview H5与应用通信
H5端: 1、找到index.html引入依赖 <script type"text/javascript" src"https://unpkg.com/dcloudio/uni-webview-js0.0.3/index.js"></script> 2、在需要通讯处发送消息 uni.postMessage({data:{code:200,msg:"处理完成&q…...
Android OpenGL ES详解——绘制圆角矩形
1、绘制矩形 代码如下: renderer类: package com.example.roundrectimport android.content.Context import android.opengl.GLES30 import android.opengl.GLSurfaceView.Renderer import com.opengllib.data.VertexArray import com.opengllib.prog…...
网络基础二
文章目录 协议定制,序列化和反序列化应用层网络版计算器协议的定制序列反序列化序列化未复用版 反序列化 TCP是面向字节流的,你怎么保证,你读取上来的数据,是‘’一个“ “完整””的报文呢? 我们没有区分字符串里面有…...
从Full-Text Search全文检索到RAG检索增强
从Full-Text Search全文检索到RAG检索增强 时光飞逝,转眼间六年过去了,六年前铁蛋优化单表千万级数据查询性能的场景依然历历在目,铁蛋也从最开始做CRUD转行去了大数据平台开发,混迹包装开源的业务,机缘巧合下做了实时…...
springMVC 全局异常统一处理
全局异常处理⽅式⼀: 1、配置简单异常处理器 配置 SimpleMappingExceptionResolver 对象: <!-- 配置全局异常统⼀处理的 Bean (简单异常处理器) --> <bean class"org.springframework.web.servlet.handler.SimpleMappingExceptionReso…...
qt ubuntu i386 系统
sudo ln -s cmake-3.31.0-linux-x86_64/bin/* /usr/local/bin 【Ubuntu20.4安装QT6 - CSDN App】Ubuntu20.4安装QT6_ubuntu安装qt6-CSDN博客 sudo ../configure -release -platform linux-g-64 -static -nomake examples -nomake demos -no-qt3support -no-script -no-scriptt…...
BUUCTF—Reverse—helloword(6)
一道安卓逆向的签到题 下载附件 使用JADX-gui反编译工具打开(注意配环境),找到主函数 jadx 本身就是一个开源项目,源代码已经在 Github 上开源了 官方地址:GitHub - skylot/jadx: Dex to Java decompiler 发现flag …...
深入解析下oracle date底层存储方式
之前我们介绍了varchar2和char的数据库底层存储格式,今天我们介绍下date类型的数据存储格式,并通过测试程序快速获取一个日期。 一、环境搭建 1.1,创建表 我们还是创建一个测试表t_code,并插入数据: 1.2,…...
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
作者:来自 Elastic Saikat Sarkar 使用 Elasticsearch 向量数据库构建搜索 AI 体验时如何使用 IBM watsonx™ Slate 文本嵌入。 Elastic 很高兴地宣布,通过集成 IBM watsonx™ Slate 嵌入模型,我们的开放推理 API 功能得以扩展,这…...
如何搭建一个小程序:从零开始的详细指南
在当今数字化时代,小程序以其轻便、无需下载安装即可使用的特点,成为了连接用户与服务的重要桥梁。无论是零售、餐饮、教育还是娱乐行业,小程序都展现了巨大的潜力。如果你正考虑搭建一个小程序,本文将为你提供一个从零开始的详细…...
NFS搭建
NFS搭建 单节点安装配置服务器安装配置启动并使NFS服务开机自启客户端挂载查看是否能发现服务器的共享文件夹创建挂载目录临时挂载自动挂载 双节点安装配置服务器安装配置服务端配置NFS服务端配置Keepalived编辑nfs_check.sh监控脚本安装部署RsyncInofity 客户端 单节点安装配置…...
RNN与LSTM,通过Tensorflow在手写体识别上实战
简介:本文从RNN与LSTM的原理讲起,在手写体识别上进行代码实战。同时列举了优化思路与优化结果,都是基于Tensorflow1.14.0的环境下,希望能给您的神经网络学习带来一定的帮助。如果您觉得我讲的还行,希望可以得到您的点赞…...
Docker部署FastAPI实战
在现代 Web 开发领域,FastAPI 作为一款高性能的 Python 框架,正逐渐崭露头角,它凭借简洁的语法、快速的执行速度以及出色的类型提示功能,深受开发者的喜爱。而 Docker 容器化技术则为 FastAPI 应用的部署提供了便捷、高效且可移植…...
【Python数据分析五十个小案例】电影评分分析:使用Pandas分析电影评分数据,探索评分的分布、热门电影、用户偏好
博客主页:小馒头学python 本文专栏: Python数据分析五十个小案例 专栏简介:分享五十个Python数据分析小案例 在现代电影行业中,数据分析已经成为提升用户体验和电影推荐的关键工具。通过分析电影评分数据,我们可以揭示出用户的…...
Vue2学习记录
前言 这篇笔记,是根据B站尚硅谷的Vue2网课学习整理的,用来学习的 如果有错误,还请大佬指正 Vue核心 Vue简介 Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。 它基于标准 HTML、CSS 和 JavaScr…...
TMS FNC UI Pack 5.4.0 for Delphi 12
TMS FNC UI Pack是适用于 Delphi 和 C Builder 的多功能 UI 控件的综合集合,提供跨 VCL、FMX、LCL 和 TMS WEB Core 等平台的强大功能。这个统一的组件集包括基本工具,如网格、规划器、树视图、功能区和丰富的编辑器,确保兼容性和简化的开发。…...
深圳酒店设计公司/班级优化大师官方网站
接前贴:今年(2021年)7月4日至24日,我指导电子信息工程专业18级的12位同学进行小学期的课程实践。其中,王同学、万同学、高同学等3位同学完成了基于广东高云(GOWIN Semiconductor)FPGA的DDS实现。…...
海宁公司做网站/百度搜索网站排名
【一】 在新乐谱的第一小节开始添加一个全音符的中央C No.1 在New里新建一个插件 5/建中央C (User copy) No.2 双击打开 点run运行里输入代码 如图: No.3 点击ok 然后close关闭 No.4 点菜单栏的Plug-ins里 我新建的5插件 No.6 运行后就是这…...
现在有哪些网站兼职可以做/百度网站app下载
引用做函数參数 struct Teacher {char name[64];int age ; };void printfT(Teacher *pT) {cout<<pT->age<<endl; }//pT是t1的别名 ,相当于改动了t1 void printfT2(Teacher &pT) {//cout<<pT.age<<endl;pT.age 33; }//pT和t1的是两个不同的变量…...
tk后缀网站是什么网站/东莞今天发生的重大新闻
上一次自己写了一个多线程断点续传下载的demo,过于麻烦,bug超多,所以我学习使用xutils来完成此功能。 先将xutils依赖搭建好(上一篇博客已经具体写了方法) 先看看效果图: 下面开始代码的逻辑: 在…...
网站开发策划个人简历/百度搜索引擎的特点
当前,物联网技术正在推动人类社会从“信息化”向“智能化”转变,促进信息科技与产业发生巨大变化。但目前的实际情况来看,物联网的终端设备类型多、数量大,安装运维成本高、工作量大,新业务、新功能扩展靠硬件盒子“堆…...
详述电子商务网站的建设/怎么在百度上做广告推广
【例9-23】最长公共子序列【问题描述】w一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X1,x2,…,xm>,则另一序列Z=1,z2,…,zk>是X的子序列是指存在一个严格递增的下…...