「趣学前端」曾经忽略的arguments,重新捋一捋,看有没有新收获

简介: 用技术实现梦想,用梦想打开前端技术之门。曾经忽略的arguments,重新捋一捋,看有没有新收获。

前言

众所周知,前端知识体系繁杂,需要掌握的内容瀚如星海。然而星河璀璨,学习和实践的过程很有趣,但是我自身体会,不知道为何有些知识点比较容易被忽略。

今日分享的arguments对象,就是曾经被我忽略的内容之一,当我再次遇见它,发现它的有趣之处时,我决定把它写下来。

它是一个对应于传递给函数的参数的类数组对象。什么情况下会用到它?怎么用?不着急,我们先从一道面试题说起。

一道看似简单的面试题

一道题

最早发现我忽略了它,是从一道面试题开始的。

varlength=10functionfn() {
console.log(this.length)
}
varobj= {
length: 5,
method: function(fn) {
arguments[0](); 
  }
}
obj.method(fn,1);

这道题的主要干扰是两处声明的length的变量,当你第一反应是全局的length变量,还是obj的属性length时,你已经离正确答案越来越远了。我们不妨先把正确答案打印出来,答案是2。

image.jpeg

一个答案

这个答案,熟悉的人不难,不熟的人会有点困惑。解题的关键点在于arguments对象。

arguments是一个类数组对象,它包含传递给函数的每个参数,可以通过索引取出函数的每一个参数,比如上面的题目我们打印一下arguments[0]。

varlength=10;
functionfn() {
console.log(this.length);
}
varobj= {
length: 5,
method: function (fn) {
console.log(arguments[0]); // [Function: fn]  },
};
obj.method(fn, 1);

arguments[0]打印出来是fn函数,也就是obj.method的第一个参数。arguments[0]()也就相当于fn(),而fn函数执行的结果是打印length,是谁的length属性,是全局变量length?还是obj的length?

很显然都不是,因为2≠10并且2≠5。这两个问句也正是我前面提到的干扰点,这题很巧妙的设置了一个迷雾阵,让人很容易忽略解题的关键点。

一种技巧

我们先打印一下this,会发现结果和直接打印arguments是一致的,所以此处的this指向的是arguments对象。我们知道,在函数中,this指向的是调用它的函数,所以此处调用的正是arguments。

varlength=10;
functionfn() {
console.log(this); // [Arguments] { '0': [Function: fn], '1': 1 }// console.log(this.length);}
varobj= {
length: 5,
method: function (fn) {
arguments[0]();
console.log(arguments); //[Arguments] { '0': [Function: fn], '1': 1 }  },
};
obj.method(fn, 1);

arguments的length属性指向传递给当前函数的参数数量。obj.method传递的参数有两个,所以arguments.length打印出来是2。

我们重新看这道题目,题目看似简单,但是可能没办法立刻想到结果是什么。这个时候,莫慌,试着将问题分解,将问题分解成知识点,思路也就清晰了。

面试题分析完,也就大致了解了arguments是什么以及怎么用了。


arguments对象

下面,我们来详细的了解一下arguments对象。以下内容大部分来自MDN

语法

arguments 是一个对应于传递给函数的参数的类数组对象它包含传递给函数的每个参数,可以根据索引值引用需要的参数,例如:

functionfn () {
console.log(arguments[0]) // arg1console.log(arguments[1]) // arg2console.log(arguments[2]) // arg3}
fn('arg1','arg2','arg3')


属性

arguments.callee

指向参数所属的当前执行的函数。

functionfn () {
console.log(arguments.callee) // [Function: fn]}
fn('arg1','arg2','arg3')


arguments.length

传递给函数的参数数量。

functionfn () {
console.log(arguments.length); // 3}
fn('arg1','arg2','arg3');


arguments[@@iterator]

返回一个新的Array 迭代器 对象,该对象包含参数中每个索引的值。

functionfn () {
console.log(arguments[Symbol.iterator]); // [Function: values]}
fn('arg1','arg2','arg3');


实用例子

通过arguments的属性,处理函数入参,尤其参数不定时,是很好用的。且可以通过控制默认参数和实参,达到我们想要的结果。

遍历参数求和

arguments是一个对应于传递给函数的参数的类数组对象,所以可以通过遍历它的所有值,进行求值操作。

functionadd() {
varsum=0,
len=arguments.length;
for (vari=0; i<len; i++) {
sum+=arguments[i];
  }
returnsum;
}
add(); // 0add(1); // 1add(1, 2, 3, 4); // 10

定义连接字符串的函数

这个例子定义了一个函数来连接字符串。这个函数唯一正式声明了的参数是一个字符串,该参数指定一个字符作为衔接点来连接字符串。

可以传递任意数量的参数到该函数,并使用每个参数作为列表中的项创建列表。

functionmyConcat(separator) {
varargs=Array.prototype.slice.call(arguments, 1);
returnargs.join(separator);
}
// returns "red, orange, blue"myConcat(", ", "red", "orange", "blue");
// returns "elephant; giraffe; lion; cheetah"myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
// returns "sage. basil. oregano. pepper. parsley"myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");


剩余参数、默认参数和解构赋值参数

arguments对象可以与剩余参数、默认参数和解构赋值参数结合使用。

在严格模式下,剩余参数、默认参数和解构赋值参数的存在不会改变 arguments对象的行为,但是在非严格模式下就有所不同了。

当非严格模式中的函数没有包含剩余参数、默认参数和解构赋值,那么arguments对象中的值会跟踪参数的值(反之亦然)。

// 没有包含剩余参数、默认参数和解构赋值,更新了arguments[0],同样更新了afunctionfunc(a) {
arguments[0] =99;
console.log(a);
}
func(10); // 99// 没有包含剩余参数、默认参数和解构赋值,更新了a,同样更新了arguments[0]functionfunc(a) {
a=99;
console.log(arguments[0]);
}
func(10); // 99// 包含解构赋值参数,更新了arguments[0],没有更新afunctionfunc(a=55) {
arguments[0] =99; 
console.log(a);
}
func(10); // 10// 包含默认参数,更新了a的值,没有改变arguments[0]的值functionfunc(a=55) {
arguments[0] =99; // updating arguments[0] does not also update aconsole.log(a);
}
func(10); // 10


总结

无论是面试题,还是日常工作中,我们时常会有这样的困惑,实际的结果和我们预想的结果不一致,于是我们回过头来梳理,我们到底遗漏了什么。在我过往的经验中,半数以上的此类情况,皆因我对某块知识的掌握的不全面,导致自己的代码结果出现偏差。

一花一世界,一叶一菩提。通过一个个知识点去梳理整个功能开发走向,每次将问题解决,我都会把知识点补全。因而也让我在后续的工作中,无论是开发还是日常解决问题,都是快速且高质的。

坚持做好一件事不容易,但是最终得到的收获却是超值的。

目录
打赏
0
0
1
0
1101
分享
相关文章
前端基础(十一)_函数声明及调用、函数的形参与实参、arguments参数、函数的参数类型、函数中的问题
本文介绍了JavaScript中函数的声明及调用、形参与实参的概念、arguments对象的使用、函数参数的类型以及函数中this的作用。通过示例代码详细解释了函数如何接收参数、如何处理参数个数不匹配的情况,以及函数在不同上下文中this的指向。
63 1
【面试题】5年前端 - 历时1个月收获7个offer
【面试题】5年前端 - 历时1个月收获7个offer
497 0
前端学习笔记202304学习笔记第九天-收获
前端学习笔记202304学习笔记第九天-收获
87 0
前端知识案例32-javascript基础语法-arguments
前端知识案例32-javascript基础语法-arguments
73 0
前端知识案例32-javascript基础语法-arguments
第十六届 D2 前端技术论坛完成 6 大专场 21 个话题集结,快来划重点,你一定会有所收获!
一年一度的前端盛会D2前端技术论坛就要来啦,话题集结完成,快来报名学习吧!
1657 0
第十六届 D2 前端技术论坛完成 6 大专场 21 个话题集结,快来划重点,你一定会有所收获!
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
332 14
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
108 6
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
110 1

热门文章

最新文章

  • 1
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    14
  • 2
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    22
  • 3
    详解智能编码在前端研发的创新应用
    17
  • 4
    巧用通义灵码,提升前端研发效率
    15
  • 5
    智能编码在前端研发的创新应用
    7
  • 6
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    24
  • 7
    VSCode AI提效工具,通义灵码前端开发体验
    71
  • 8
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    9
  • 9
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    11
  • 10
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    6
  • 1
    无前端经验如何快速搭建游戏站:使用 windsurf 从零到上线的详细指南
    24
  • 2
    【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
    33
  • 3
    VSCode AI提效工具,通义灵码前端开发体验
    71
  • 4
    开箱即用的GO后台管理系统 Kratos Admin - 前端权限
    9
  • 5
    以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
    37
  • 6
    大前端之前端开发接口测试工具postman的使用方法-简单get接口请求测试的使用方法-简单教学一看就会-以实际例子来说明-优雅草卓伊凡
    71
  • 7
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    31
  • 8
    巧用通义灵码,提升前端研发效率
    101
  • 9
    【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    151
  • 10
    详解智能编码在前端研发的创新应用
    110