当前位置: 首页 > 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 生态系统的不断演进,掌握这些特性不仅能提升开发效率,还能让我们编写出更具现代化风格、更符合最佳实践代码

在这里插入图片描述


http://www.lryc.cn/news/492440.html

相关文章:

  • Android 布局菜单或按钮图标或Menu/Item设置可见和不可见
  • || 与 ??的区别
  • wordpress获取文章总数、分类总数、tag总数等
  • pytest 通过实例讲清单元测试、集成测试、测试覆盖率
  • C#里怎么样自己实现10进制转换为二进制?
  • Kafka-Consumer理论知识
  • Js-对象-04-Array
  • React 第八节组件生命周期钩子-类式组件,函数式组件模拟生命周期用法
  • Dubbo源码解析-服务调用(七)
  • svn 崩溃、 cleanup失败 怎么办
  • 【Linux系列】NTP时间同步服务器搭建完整指南
  • go 结构体方法
  • DHCP服务(包含配置过程)
  • uniapp内嵌的webview H5与应用通信
  • Android OpenGL ES详解——绘制圆角矩形
  • 网络基础二
  • 从Full-Text Search全文检索到RAG检索增强
  • springMVC 全局异常统一处理
  • qt ubuntu i386 系统
  • BUUCTF—Reverse—helloword(6)
  • 深入解析下oracle date底层存储方式
  • Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
  • 如何搭建一个小程序:从零开始的详细指南
  • NFS搭建
  • RNN与LSTM,通过Tensorflow在手写体识别上实战
  • Docker部署FastAPI实战
  • 【Python数据分析五十个小案例】电影评分分析:使用Pandas分析电影评分数据,探索评分的分布、热门电影、用户偏好
  • Vue2学习记录
  • TMS FNC UI Pack 5.4.0 for Delphi 12
  • Redis主从架构