JavaScript 中 arguments、类数组与数组的深入解析


在这里插入图片描述

博客主页: [小ᶻZ࿆]
本文专栏: 前端

文章目录

  • 💯前言
  • 💯什么是 `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.mzph.cn/pingmian/61493.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTTP 协议的作用

HTTP 主要用于在客户端&#xff08;如 Web 浏览器&#xff09;和服务器之间传输超文本&#xff08;如 HTML 文档&#xff09;以及其他类型的数据&#xff08;如图片、视频、文件等&#xff09;。HTTP 协议的主要作用可以概括为如下几点&#xff1a; 信息交换&#xff1a; HTTP…

开源生态发展合作倡议

在信息技术发展的浪潮中&#xff0c;开源已成为全球创新的强劲引擎&#xff0c;深刻影响着各行各业的发展。今天&#xff0c;我们站在新的历史起点上&#xff0c;肩负着推动开源生态发展的重任。在此&#xff0c;开源欧拉&#xff08;openEuler&#xff09;、龙蜥&#xff08;O…

设计模式-创建型-抽象工厂模式

1.概念 工厂方法模式只能生产一个产品系列&#xff0c;抽象工厂可以生产多个产品系列 2.作用 多个具体产品组成一个产品族&#xff08;产品系列&#xff09;&#xff0c;一个具体工厂负责生产一个产品族 3.应用场景 系统所需产品间由依赖关系&#xff0c;可以划分为同一产…

智能合约运行原理

点个关注吧&#xff01;&#xff01; 用一句话来总结&#xff0c;智能合约就像是一个自动售货机&#xff1a;你投入硬币&#xff08;触发条件&#xff09;&#xff0c;选择商品&#xff08;执行合约&#xff09;&#xff0c;然后机器就会自动给你商品&#xff08;执行结果&…

结合第三方模块requests,文件IO、正则表达式,通过函数封装爬虫应用采集数据

#引用BeautifulSoup更方便提取html信息&#xff1b;requests模块&#xff0c;发生http请求&#xff1b;os模块&#xff0c;文件写入import requests from bs4 import BeautifulSoup import os#当使用requests库发送请求时&#xff0c;如果不设置User - Agent&#xff0c;默认的…

操作系统基础——针对实习面试

目录 操作系统基础什么是操作系统&#xff1f;简述其主要功能请举例几种不同类型的操作系统&#xff0c;并简要说明它们的特点 操作系统基础 什么是操作系统&#xff1f;简述其主要功能 一、操作系统的定义 操作系统&#xff08;Operating System&#xff0c;简称OS&#xff…

深度学习基础练习:代码复现transformer重难点

2024/11/10-2024/11/18: 主要对transformer一些比较难理解的点做了一些整理&#xff0c;希望对读者有所帮助。 前置知识&#xff1a; 深度学习基础练习&#xff1a;从pytorch API出发复现LSTM与LSTMP-CSDN博客 【神经网络】学习笔记十四——Seq2Seq模型-CSDN博客 【官方双语】一…

ESLint的简单使用(js,ts,vue)

一、ESLint介绍 1.为什么要用ESLint 统一团队编码规范&#xff08;命名&#xff0c;格式等&#xff09; 统一语法 减少git不必要的提交 减少低级错误 在编译时检查语法&#xff0c;而不是等js引擎运行时才检查 2.eslint用法 可以手动下载配置 可以通过vue脚手架创建项…

WPF中DataGrid滚动条自动滚动到文字编辑行的实现方法

文章目录 1.需求分析2. 实现步骤3.完整示例4.总结 在 WPF 中&#xff0c;DataGrid 是一个强大的控件&#xff0c;常常用于显示和编辑数据。有时&#xff0c;我们希望当用户在某一行开始编辑时&#xff0c;DataGrid 自动滚动到该行的位置&#xff0c;确保用户能够看到完整的内容…

算法学习笔记(一):滑动窗口和双指针

滑动窗口套路&#xff1a; 核心套路三步骤&#xff1a; 1.入&#xff1a; 下标为 i 的元素进入窗口&#xff0c;更新相关统计量(因为一个元素进入了&#xff0c;则相关统计的数据要更新&#xff0c;就是)&#xff0c;然后进行判断&#xff0c;如果i < k - 1 则continue&…

探索PDFMiner:Python中的PDF解析利器

文章目录 **探索PDFMiner&#xff1a;Python中的PDF解析利器**1. 背景介绍&#xff1a;为何选择PDFMiner&#xff1f;2. PDFMiner是什么&#xff1f;3. 如何安装PDFMiner&#xff1f;4. 简单库函数使用方法4.1 提取文本4.2 获取页面布局信息4.3 提取表格数据4.4 提取图像 5. 应…

前端开发调试之移动端调试学习笔记

一、引言 随着移动互联网的飞速发展&#xff0c;移动端页面和应用的开发变得越发重要。而在前端开发移动端项目时&#xff0c;有效的调试手段能帮助我们及时发现并解决诸多问题&#xff0c;确保项目在移动端设备上能够正常运行且提供良好的用户体验。以下就是关于前端开发中移动…

徒手从零搭建一套ELK日志平台

徒手从零搭建一套ELK日志平台 日志分析的概述日志分析的作用主要收集工具集中式日志系统主要特点采集日志分类ELK概述初级版ELK终极版ELK高级版ELKELK收集日志的两种形式 搭建ELK平台Logstash工作原理Logstash核心概念环境准备安装部署docker添加镜像加速器安装部署Elasticsear…

02 —— Webpack 修改入口和出口

概念 | webpack 中文文档 | webpack中文文档 | webpack中文网 修改入口 webpack.config.js &#xff08;放在项目根目录下&#xff09; module.exports {//entry设置入口起点的文件路径entry: ./path/to/my/entry/file.js, }; 修改出口 webpack.config.js const path r…

LSTM 和 LSTMCell

1. LSTM 和 LSTMCell 的简介 LSTM (Long Short-Term Memory): 一种特殊的 RNN&#xff08;循环神经网络&#xff09;&#xff0c;用于解决普通 RNN 中 梯度消失 或 梯度爆炸 的问题。能够捕获 长期依赖关系&#xff0c;适合处理序列数据&#xff08;如自然语言、时间序列等&…

23种设计模式-模板方法(Template Method)设计模式

文章目录 一.什么是模板方法模式&#xff1f;二.模板方法模式的特点三.模板方法模式的结构四.模板方法模式的应用场景五.模板方法模式的优缺点六.模板方法模式的C实现七.模板方法模式的JAVA实现八.代码解析九.总结 类图&#xff1a; 模板方法设计模式类图 一.什么是模板方法模…

MySQL45讲 第二十五讲 高可用性深度剖析:从主备原理到策略选择

文章目录 MySQL45讲 第二十五讲 高可用性深度剖析&#xff1a;从主备原理到策略选择一、MySQL 主备基础原理&#xff08;一&#xff09;主备关系与数据同步&#xff08;二&#xff09;主备切换流程 二、主备延迟分析&#xff08;一&#xff09;主备延迟的定义与计算&#xff08…

一篇文章了解机器学习(下)

一、决策树 1、主要应用场景为分类的问题。采用“树”的理念&#xff0c;通过计算数据的信息熵确定树的根节点、channel&#xff0c;从而加快数据分类。 注&#xff1a;与常规二分类树的区别&#xff1a;决策树中通过依据树的广度与深度&#xff0c;不断确定根节点的root值&a…

深入解析QP算法及其Python实现

目录 深入解析QP算法及其Python实现第一部分:QP算法的基本原理与数学模型1.1 QP问题定义1.2 算法核心思想1.3 应用场景第二部分:QP算法的Python实现(面向对象设计)2.1 核心代码实现第三部分:案例1 - 投资组合优化问题(策略模式)3.1 问题描述3.2 代码实现3.3 设计模式分析…

VuePress v2 快速搭建属于自己的个人博客网站

目录 为什么用VuePress&#xff1f; 一、前期准备 Node.js 使用主题快速开发 二、VuePress安装 三、个性化定制 修改配置信息 删除不需要的信息 博客上传 四、部署 使用github快速部署 初始化仓库 本地配置 配置github的ssh密钥 部署 为什么用VuePress&#xff…