当前位置: 首页 > news >正文

【前端】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 的值是只读的,不能随意修改,否则可能会导致不可预期的行为。
  • 不是真正的数组:它虽然看起来像数组,但并不是真正的数组,无法直接使用数组的方法(例如 pushmap 等)。如果需要使用这些方法,我们通常需要将 arguments 转换为真正的数组。
  • 存在于普通函数中arguments 仅在普通函数中有效,在箭头函数中不存在。这是因为箭头函数没有自己的 arguments 对象,它们会从包含它们的父级作用域中继承 arguments
  • 性能警告:在现代 JavaScript 中,arguments 对象已经逐渐被剩余参数语法(...rest)取代,因为后者更加高效和直观。尤其是在涉及到复杂操作和高性能需求的情况下,剩余参数的表现通常要优于 arguments

2.3 使用场景

在这里插入图片描述

arguments 在以下情况下非常有用:

  1. 处理未知数量的参数
    在不知道函数调用时会传入多少个参数的情况下,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
    
  2. 实现灵活的参数接口
    在没有使用 ES6 剩余参数语法的旧代码中,arguments 是处理灵活参数的主要工具。这些代码通常需要处理不固定数量的参数,并且不方便直接修改函数定义,此时 arguments 显得尤为重要。

  3. 函数重载实现
    在一些场景下,可能会需要根据传入参数的不同类型或数量来执行不同的逻辑。虽然 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 属性。
  • 不能直接使用数组的原型方法(例如 pushmap 等)。

类数组对象是广泛存在于 JavaScript 中的数据结构,常见的类数组对象包括:

常见的类数组对象:

  1. arguments 对象:捕获函数调用时传入的所有参数。
  2. NodeList(Document Object Model 操作中的节点列表,用于包含由选择器或其他查询方法返回的元素集合)。
  3. HTMLCollection(通过 getElementsByClassName 返回的集合)。

类数组和数组的主要区别

在这里插入图片描述

特性类数组数组
类型ObjectArray
检测方式typeof 返回 objectArray.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);

这些方法的核心目的是将类数组对象转换为一个真正的数组,以便我们能够使用数组的各种方法(如 mapfilter 等),从而更方便地进行数据操作。


💯箭头函数与 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 优势

在这里插入图片描述

  1. 返回真正的数组
    • 不需要额外的转换操作。
  2. 简洁明亮
    • 代码更加直观和易读。
  3. 更好的可维护性
    • 剩余参数的代码结构更简洁、逻辑更清晰,便于团队协作和代码审查。

💯总结与最佳实践

在这里插入图片描述


7.1 使用场景建议

在这里插入图片描述

  • 如果需要兼容旧版 JavaScript,且需要访问所有参数,仍可以使用 arguments
  • 在现代开发中,优先使用剩余参数替代 arguments,以简化代码逻辑。剩余参数的灵活性使其能够适应更多的场景,尤其是在函数需要处理可变数量参数时表现更优。

7.2 转换类数组的首选方法

在这里插入图片描述

  • 使用 Array.from 或扩展运算符(...)来将类数组对象转换为数组。这些方法能够更高效、更直观地完成转换,并且代码的可读性更好。

7.3 常见误区

在这里插入图片描述

  1. 误以为 arguments 是数组

    • 需要明确 arguments 是类数组,而非真正的数组。
    • 若直接调用数组方法会导致报错。例如,尝试对 arguments 调用 map() 方法会导致 TypeError
  2. 在箭头函数中使用 arguments

    • 箭头函数不支持 arguments,需要通过剩余参数捕获参数。因为箭头函数的 this 和作用域继承自父级上下文,它们不生成自己的 arguments 对象。

💯小结

  • 在这里插入图片描述
    通过这篇文章,我们深入探讨了 JavaScript 中 arguments 对象的定义特性、应用场景,以及类数组与数组的区别,并结合现代语法如剩余参数对其进行了优化替代的说明。理解这些内容将帮助我们在日常开发中更高效地处理函数参数问题,同时编写出更简洁易于维护的代码。随着 JavaScript 生态系统的不断演进,掌握这些特性不仅能提升开发效率,还能让我们编写出更具现代化风格、更符合最佳实践代码

在这里插入图片描述


相关文章:

【前端】JavaScript 中 arguments、类数组与数组的深入解析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是 arguments 对象2.1 arguments 的定义2.2 arguments 的特性2.3 使用场景 &#x1f4af;深入了解 arguments 的结构3.1 arguments 的内部结构arguments 的关键属性…...

Android 布局菜单或按钮图标或Menu/Item设置可见和不可见

设置可见和不可见 即 设置 显示和隐藏&#xff1b;是双向设置&#xff1b;什么情况显示&#xff0c;什么情况隐藏分判断的条件 它不同于删除和屏蔽&#xff0c;删除和屏蔽&#xff0c;覆盖是单向的&#xff0c;不可逆转的。它间接等于单向的隐藏&#xff01;&#xff01;&…...

|| 与 ??的区别

?? : 空值合并运算符&#xff0c; 用于在左侧操作数为 null 或 undefined 时返回右侧操作数 let name null // null 或者 undefinedlet defaultName defaultNamelet displayName name ?? defaultNameconsole.log(displayName) // defaultName || : 逻辑或&#xff0c;…...

wordpress获取文章总数、分类总数、tag总数等

在制作wordpress模板的时候会要调用网站的文章总数分类总数tag总数等这个数值&#xff0c;如果直接用count查询数据库那就太过分了。好在wordpress内置了一些标签可以直接获取到这些数值&#xff0c;本文整理了一些常用的wordpress网站总数标签。 文章总数 <?php $count_…...

pytest 通过实例讲清单元测试、集成测试、测试覆盖率

1. 单元测试 概念 定义: 单元测试是对代码中最小功能单元的测试&#xff0c;通常是函数或类的方法。目标: 验证单个功能是否按照预期工作&#xff0c;而不依赖其他模块或外部资源。特点: 快速、独立&#xff0c;通常是开发者最先编写的测试。 示例&#xff1a;pytest 实现单…...

C#里怎么样自己实现10进制转换为二进制?

C#里怎么样自己实现10进制转换为二进制&#xff1f; 很多情况下&#xff0c;我们都是采用C#里类库来格式化输出二进制数。 如果有人要你自己手写一个10进制数转换为二进制数&#xff0c;并格式化输出&#xff0c; 就可以采用本文里的方法。 这里采用求模和除法来实现的。 下…...

Kafka-Consumer理论知识

一、上下文 之前的博客我们分析了Kafka的设计思想、Kafka的Producer端、Kafka的Server端的分析&#xff0c;为了完整性&#xff0c;我们接下来分析下Kafka的Consumer。《Kafka-代码示例》中有对应的Consumer示例代码&#xff0c;我们以它为入口进行分析 二、KafkaConsumer是什…...

Js-对象-04-Array

重点关注&#xff1a;Array String JSON BOM DOM Array Array对象时用来定义数组的。常用语法格式有如下2种&#xff1a; 方式1&#xff1a; var 变量名 new Array(元素列表); 例如&#xff1a; var arr new Array(1,2,3,4); //1,2,3,4 是存储在数组中的数据&#xff0…...

React 第八节组件生命周期钩子-类式组件,函数式组件模拟生命周期用法

概述 React组件的生命周期可以分为三个主要阶段&#xff1a; 挂载阶段&#xff08;Mounting&#xff09;&#xff1a;组件被创建&#xff0c;插入到DOM 树的过程&#xff1b; 更新阶段&#xff08;Updating&#xff09;&#xff1a;是组件中 props 以及state 发生变化时&#…...

Dubbo源码解析-服务调用(七)

一、服务调用流程 服务在订阅过程中&#xff0c;把notify 过来的urls 都转成了invoker&#xff0c;不知道大家是否还记得前面的rpc 过程&#xff0c;protocol也是在服务端和消费端各连接子一个invoker&#xff0c;如下图&#xff1a; 这张图主要展示rpc 主流程&#xff0c;消费…...

svn 崩溃、 cleanup失败 怎么办

在使用svn的过程中&#xff0c;可能出现整个svn崩溃&#xff0c; 例如cleanup 失败的情况&#xff0c;类似于 这时可以下载本贴资源文件并解压。 或者直接访问网站 SQLite Download Page 进行下载 解压后得到 sqlite3.exe 放到发生问题的svn根目录的.svn路径下 右键呼出pow…...

【Linux系列】NTP时间同步服务器搭建完整指南

在分布式系统和高可用环境中&#xff0c;时间同步是至关重要的。特别是对于银行、金融等关键业务系统&#xff0c;精准的时间同步不仅关系到系统的稳定性&#xff0c;还直接影响交易处理、日志管理、日终结算等功能。本文将介绍NTP&#xff08;Network Time Protocol&#xff0…...

go 结构体方法

在 Go 语言中&#xff0c;结构体方法是指附加到结构体类型上的函数。这些方法可以通过结构体的实例来调用。方法的接收者&#xff08;receiver&#xff09;指定了该方法属于哪个结构体类型。接收者可以是一个值类型或指针类型。 定义结构体方法 下面是如何为一个结构体定义方…...

DHCP服务(包含配置过程)

目录 一、 DHCP的定义 二、 使用DHCP的好处 三、 DHCP的分配方式 四、 DHCP的租约过程 1. 客户机请求IP 2. 服务器响应 3. 客户机选择IP 4. 服务器确定租约 5. 重新登录 6. 更新租约 五、 DHCP服务配置过程 一、 DHCP的定义 DHCP&#xff08;Dynamic Host Configur…...

uniapp内嵌的webview H5与应用通信

H5端&#xff1a; 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、绘制矩形 代码如下&#xff1a; renderer类&#xff1a; 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…...

网络基础二

文章目录 协议定制&#xff0c;序列化和反序列化应用层网络版计算器协议的定制序列反序列化序列化未复用版 反序列化 TCP是面向字节流的&#xff0c;你怎么保证&#xff0c;你读取上来的数据&#xff0c;是‘’一个“ “完整””的报文呢&#xff1f; 我们没有区分字符串里面有…...

从Full-Text Search全文检索到RAG检索增强

从Full-Text Search全文检索到RAG检索增强 时光飞逝&#xff0c;转眼间六年过去了&#xff0c;六年前铁蛋优化单表千万级数据查询性能的场景依然历历在目&#xff0c;铁蛋也从最开始做CRUD转行去了大数据平台开发&#xff0c;混迹包装开源的业务&#xff0c;机缘巧合下做了实时…...

springMVC 全局异常统一处理

全局异常处理⽅式⼀: 1、配置简单异常处理器 配置 SimpleMappingExceptionResolver 对象: <!-- 配置全局异常统⼀处理的 Bean &#xff08;简单异常处理器&#xff09; --> <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…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

02.运算符

目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&&#xff1a;逻辑与 ||&#xff1a;逻辑或 &#xff01;&#xff1a;逻辑非 短路求值 位运算符 按位与&&#xff1a; 按位或 | 按位取反~ …...