「知识点」曾经忽略的 arguments
前言
众所周知,前端知识体系繁杂,需要掌握的内容瀚如星海。然而星河璀璨,学习和实践的过程很有趣,但是我自身体会,不知道为何有些知识点比较容易被忽略。
今日分享的 arguments 对象,就是曾经被我忽略的内容之一,当我再次遇见它,发现它的有趣之处时,我决定把它写下来。
它是一个对应于传递给函数的参数的类数组对象。什么情况下会用到它?怎么用?不着急,我们先从一道面试题说起。
一道看似简单的面试题
一道题
最早发现我忽略了它,是从一道面试题开始的。
这道题的主要干扰是两处声明的 length 的变量,当你第一反应是全局的 length 变量,还是 obj 的属性 length 时,你已经离正确答案越来越远了。我们不妨先把正确答案打印出来,答案是 2。
一个答案
这个答案,熟悉的人不难,不熟的人会有点困惑。解题的关键点在于 arguments 对象。
arguments 是一个类数组对象,它包含传递给函数的每个参数,可以通过索引取出函数的每一个参数,比如上面的题目我们打印一下 arguments[0]。
arguments[0]打印出来是 fn 函数,也就是 obj.method 的第一个参数。arguments0也就相当于 fn(),而 fn 函数执行的结果是打印 length,是谁的 length 属性,是全局变量 length?还是 obj 的 length?很显然都不是,因为 2≠10 并且 2≠5。这两个问句也正是我前面提到的干扰点,这题很巧妙的设置了一个迷雾阵,让人很容易忽略解题的关键点。
一种技巧
我们先打印一下 this,会发现结果和直接打印 arguments 是一致的,所以此处的 this 指向的是 arguments 对象。我们知道,在函数中,this 指向的是调用它的函数,所以此处调用的正是 arguments。
arguments 的 length 属性指向传递给当前函数的参数数量。obj.method 传递的参数有两个,所以 arguments.length 打印出来是 2。
我们重新看这道题目,题目看似简单,但是可能没办法立刻想到结果是什么。这个时候,莫慌,试着将问题分解,将问题分解成知识点,思路也就清晰了。
面试题分析完,也就大致了解了 arguments 是什么以及怎么用了。
arguments 对象
下面,我们来详细的了解一下 arguments 对象。以下内容大部分来自MDN。
语法
arguments 是一个对应于传递给函数的参数的类数组对象。它包含传递给函数的每个参数,可以根据索引值引用需要的参数,例如:
属性
arguments.callee
指向参数所属的当前执行的函数。
arguments.length
传递给函数的参数数量。
arguments[@@iterator]
返回一个新的 Array 迭代器 对象,该对象包含参数中每个索引的值。
实用例子
通过 arguments 的属性,处理函数入参,尤其参数不定时,是很好用的。且可以通过控制默认参数和实参,达到我们想要的结果。
遍历参数求和
arguments 是一个对应于传递给函数的参数的类数组对象,所以可以通过遍历它的所有值,进行求值操作。
定义连接字符串的函数
这个例子定义了一个函数来连接字符串。这个函数唯一正式声明了的参数是一个字符串,该参数指定一个字符作为衔接点来连接字符串。
可以传递任意数量的参数到该函数,并使用每个参数作为列表中的项创建列表。
剩余参数、默认参数和解构赋值参数
arguments 对象可以与剩余参数、默认参数和解构赋值参数结合使用。
在严格模式下,剩余参数、默认参数和解构赋值参数的存在不会改变 arguments 对象的行为,但是在非严格模式下就有所不同了。
当非严格模式中的函数没有包含剩余参数、默认参数和解构赋值,那么 arguments 对象中的值会跟踪参数的值(反之亦然)。
总结
无论是面试题,还是日常工作中,我们时常会有这样的困惑,实际的结果和我们预想的结果不一致,于是我们回过头来梳理,我们到底遗漏了什么。在我过往的经验中,半数以上的此类情况,皆因我对某块知识的掌握的不全面,导致自己的代码结果出现偏差。
一花一世界,一叶一菩提。通过一个个知识点去梳理整个功能开发走向,每次将问题解决,我都会把知识点补全。因而也让我在后续的工作中,无论是开发还是日常解决问题,都是快速且高质的。
坚持做好一件事不容易,但是最终得到的收获却是超值的。ヾ(◍°∇°◍)ノ゙
版权声明: 本文为 InfoQ 作者【叶一一】的原创文章。
原文链接:【http://xie.infoq.cn/article/77fcb77521f9730abb048d6c9】。文章转载请联系作者。
评论