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

js中【argument】知识点详解

最近很多读者反馈很久之前的那边关于**arguments** 的文章,讲解的不够详细,也确实,那篇文章重在讲解剩余参数和**arguments** 的比较。所以今天,哈哈哈
我又来了(傲娇脸),重新整理了一下内容,这次内容比较深入和详细

JS中【剩余参数】介绍以及与argument比较

在 JavaScript 中,arguments 是一个非常重要的概念,尤其是在处理函数参数时。这里我将详细讲解 arguments 的相关知识点,涵盖它的基本概念、特性、与 ES6 的改进以及一些常见用法。

1. 什么是 arguments 对象?

arguments 对象是 JavaScript 中所有函数内都可以使用的类数组对象。它包含传递给该函数的所有参数,允许你访问函数调用时传递的参数,即使这些参数在函数定义中没有明确列出。

主要特性:

  • 类数组arguments 对象类似于数组,但并不是一个真正的数组。它有 length 属性,但没有数组的方法,比如 forEachmap 等。
  • 函数作用域arguments 对象仅在函数体内有效,不能在全局作用域或函数外部使用。
  • 动态性:即使函数定义了参数,arguments 对象仍会包含所有传入的参数,无论这些参数是否在定义中列出。

示例代码:

function example() {console.log(arguments);
}example(1, 2, 3); // 输出: [Arguments] { '0': 1, '1': 2, '2': 3 }

在这个例子中,即使 example 函数没有定义参数,arguments 对象还是可以访问到传递给它的所有参数。

2. 访问 arguments 对象

arguments 对象的访问方式与数组类似,可以通过索引获取传递的参数值,并使用 length 属性查看传递的参数数量。

示例代码:

function add() {let sum = 0;for (let i = 0; i < arguments.length; i++) {sum += arguments[i];}return sum;
}console.log(add(1, 2, 3, 4)); // 输出: 10

在这个示例中,我们使用 arguments 对象来累加传递给函数的参数。

动态参数数量处理:

你可以传递任意数量的参数到函数中,而不需要在函数定义中明确指定。

function logAllArguments() {for (let i = 0; i < arguments.length; i++) {console.log(`Argument ${i}: ${arguments[i]}`);}
}logAllArguments('apple', 'banana', 'cherry');
// 输出:
// Argument 0: apple
// Argument 1: banana
// Argument 2: cherry

3. 与函数定义中的参数的关系

即使你在函数定义中声明了参数,arguments 对象仍然会捕获所有传递的参数。在早期的 JavaScript 中,arguments 是处理不定参数的主要方法之一。

示例代码:

function greet(name, greeting) {console.log('Name:', arguments[0]);console.log('Greeting:', arguments[1]);
}greet('Alice', 'Hello!');
// 输出:
// Name: Alice
// Greeting: Hello!

在这个例子中,arguments[0]arguments[1] 对应的是 namegreeting 参数,即使我们明确定义了这两个参数。

参数与 arguments 的同步关系:

在非严格模式下,函数参数和 arguments 是联动的。如果你修改了参数的值,arguments 对象中的对应值也会更新,反之亦然。但在严格模式下,这种行为不会发生。

function changeArg(value) {arguments[0] = 'Changed';console.log(value); // 在非严格模式下,输出 'Changed'
}changeArg('Original');

4. arguments 在严格模式下的行为

在 JavaScript 的 严格模式(strict mode) 下,arguments 对象的行为有一些不同。函数参数与 arguments 对象之间的同步关系会被破坏,即修改 arguments 中的值不会影响函数参数,反之亦然。

示例代码(严格模式下的行为):

"use strict";function changeArgStrict(value) {arguments[0] = 'Changed';console.log(value); // 输出 'Original',不会同步修改
}changeArgStrict('Original');

在严格模式下,修改 arguments 对象中的值不会影响函数的实际参数。

5. arguments 对象的局限性

虽然 arguments 对象很强大,但它有一些限制:

  • 没有数组方法arguments 是一个类数组对象,但没有像 forEachmapreduce 等数组方法。因此,如果你需要使用数组方法,你通常需要将 arguments 转换为真正的数组。

    可以通过以下方式转换:

    const argsArray = Array.prototype.slice.call(arguments);
    // 或者更简单的 ES6 写法:
    const argsArray = Array.from(arguments);
    
  • 不适用于箭头函数arguments 对象在箭头函数中不可用。箭头函数不会创建自己的 arguments 对象,而是继承自父作用域的 arguments

    示例代码:

    function outer() {const arrowFunc = () => {console.log(arguments);};arrowFunc(4, 5, 6); // 输出的是 outer 函数的 arguments,而不是 arrowFunc 的
    }outer(1, 2, 3); // 输出: [Arguments] { '0': 1, '1': 2, '2': 3 }
    

6. 使用 rest 参数替代 arguments(ES6 引入)

在 ES6 中,rest 参数(...args)为我们提供了更优雅的方式来处理不定数量的参数,并且比 arguments 对象更灵活、功能更强。

rest 参数与 arguments 的对比:

  • 真正的数组rest 参数是一个真正的数组,因此可以直接使用数组的所有方法(如 mapforEach 等)。
  • 作用域rest 参数只包含未明确列出的参数,而 arguments 包含所有参数。

示例代码:

function addES6(...args) {return args.reduce((sum, current) => sum + current, 0);
}console.log(addES6(1, 2, 3, 4)); // 输出: 10

在这个例子中,...args 是一个真正的数组,能够直接使用数组方法。

rest 参数与 arguments 的区别:

function exampleES6(arg1, ...rest) {console.log('First argument:', arg1);console.log('Rest of arguments:', rest);
}exampleES6(1, 2, 3, 4);
// 输出:
// First argument: 1
// Rest of arguments: [ 2, 3, 4 ]

这里 rest 参数只包含从第二个参数开始的值,而 arg1 是第一个参数。

7. 总结

  • arguments 对象是一个类数组对象,用于访问函数调用时传递的所有参数。
  • 它具有 length 属性,可以通过索引访问传递的参数,但没有数组的高级方法。
  • 在严格模式下,arguments 与函数参数不再同步。
  • arguments 不适用于箭头函数,它们不会创建自己的 arguments 对象。
  • ES6 引入的 rest 参数(...args)是处理不定数量参数的现代方法,比 arguments 更灵活且支持数组操作。

使用建议:

  • 在现代 JavaScript 开发中,建议使用 rest 参数来替代 arguments,因为它更简洁且功能更强大。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 技术选型对SQL与NoSQL以及Mysql,Hbase,Hive使用特性差别
  • Spring Boot-Bean注入问题
  • 无人机飞手教员组装、调试高级教学详解
  • 斗破C++编程入门系列之二十八:继承与派生:概念介绍与派生类的声明(一星斗师)
  • Neo4j入门案例:三星堆
  • 基于51单片机的心率体温监测报警系统(包括程序、仿真、原理图、流程图)
  • django学习入门系列之第十点《A 案例: 员工管理系统8》
  • ZW3D二次开发_UI_非模板表单_设置表单显示位置
  • 【网络原理】Tcp 常用提升效率机制——滑动窗口,快速重传,流量控制, 拥塞控制, 建议收藏 !!!
  • VSCode中配置C/C++环境
  • 在线仿真器ST-Link为例的整体认知
  • 科技前沿:Web3与物联网的智能连接
  • 707. 设计链表
  • CenterPoint-KITTI:环境配置、模型训练、效果展示;KITTI 3D 目标检测数据集下载
  • STM32外设之LTDC/DMA2D—液晶显示(野火)
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【css3】浏览器内核及其兼容性
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • css属性的继承、初识值、计算值、当前值、应用值
  • github从入门到放弃(1)
  • Git初体验
  • go append函数以及写入
  • Idea+maven+scala构建包并在spark on yarn 运行
  • input的行数自动增减
  • js学习笔记
  • Redis中的lru算法实现
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 简单数学运算程序(不定期更新)
  • 开源地图数据可视化库——mapnik
  • 面试遇到的一些题
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 一起参Ember.js讨论、问答社区。
  • 异步
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (二)springcloud实战之config配置中心
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (强烈推荐)移动端音视频从零到上手(下)
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • .NET gRPC 和RESTful简单对比
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .net项目IIS、VS 附加进程调试
  • /proc/vmstat 详解
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • @SuppressWarnings(unchecked)代码的作用
  • @在php中起什么作用?
  • [10] CUDA程序性能的提升 与 流