目录
JavaScript 中的参数相关知识介绍
在 JavaScript 编程中,动态参数、剩余参数和展开运算符是非常实用的特性,它们能有效提升代码的灵活性和功能性。下面将详细介绍这三个概念。
动态参数(arguments)
在 JavaScript 函数内部,存在一个内置的伪数组变量arguments,它包含了调用函数时传入的所有实参。例如:
// 求和函数,计算所有参数的和
function sum() {
let s = 0;
for (let i = 0; i < arguments.length; i++) {
s += arguments[i];
}
console.log(s);
}
// 调用求和函数
sum(5, 10); // 两个参数
sum(1, 2, 4); // 三个参数
总结起来,arguments有以下特点:
- arguments是一个伪数组,仅存在于函数中。
- 其作用是动态获取函数的实参。
- 可通过for循环依次获取传递过来的实参。
从更深入的角度看,arguments是收到的实参副本。在词法分析时,首先按形参形成AO(Activation Object,执行期上下文的变量对象)的属性,值为undefined,当实参传来时,再修改AO的相应属性,并把所有收到的实参收集起来,放到arguments对象里。它还拥有属性length,用于获取arguments对象的长度;属性callee,引用当前正在执行的函数 ,例如在递归场景中就很有用。比如求 1 到 n 的自然数之和的递归函数:
function add(n) {
if (n == 1) return 1;
else return n + arguments.callee(n - 1);
}
剩余参数
剩余参数允许我们将一个不定数量的参数表示为一个数组。语法形式为...变量名,且必须是函数的最后一个参数。例如:
function getSum(...other) {
// other 得到 [1,2,3]
console.log(other);
}
getSum(1, 2, 3);
function config(baseURL,...other) {
console.log(baseURL); // 得到 'http://baidu.com'
console.log(other); // other 得到 ['get', 'json']
}
// 调用函数
config('http://baidu.com', 'get', 'json');
总结如下:
- ...是语法符号,置于最末函数形参之前,用于获取多余的实参。
- 借助...获取的剩余实参,是个真数组,具有Array.prototype上所有的方法,这与arguments伪数组不同。
- 开发中,建议多使用剩余参数,因为它使用更方便,并且在处理参数时更符合数组的操作习惯。比如在需要对参数进行排序时,使用剩余参数的写法会简洁很多:
//arguments写法
function sortNumber() {
return Array.prototype.slice.call(arguments);
}
//rest参数写法
const sortNumber = (...numbers) => numbers.sort();
展开运算符
展开运算符(...)用于将一个数组进行展开。它有许多典型的运用场景:
- 求数组最大值 (最小值):
const arr = [1, 5, 3, 8, 2];
console.log(Math.max(...arr)); // 8
console.log(Math.min(...arr)); // 1
- 合并数组:
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [...arr1,...arr2];
console.log(arr3); // [1,2,3,4,5,6]
展开运算符主要作用是把数组展开,除了上述场景外,还能用于将类数组对象变成真正的数组对象 ,例如抓取页面中的div元素集合并转换为数组:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>盒子1</div>
<div>盒子2</div>
<script>
// 抓取元素
let divObj = document.getElementsByTagName('div');
// HTMLCollection对象类似包含html元素的一个数组
console.dir(divObj);
// 类数组对象变成数组
let list = [...divObj];
console.dir(list);
</script>
</body>
</html>
需要注意的是,展开运算符目前只能在可遍历对象(如Array、Set、String)中使用,因为它们内置了Symbol.iterator方法,而Object尚未内置该方法,所以在Object中无法直接使用展开运算符 ,不过在 ES7 草案中已加入对象展开运算符特性。
三者对比与总结
1、动态参数(arguments)与剩余参数:
- arguments是伪数组,剩余参数是真数组。
- arguments对象有callee等特殊属性和方法,剩余参数则具有数组的常规方法。
- 开发中更推荐使用剩余参数,因为它在处理参数时更方便,代码更简洁。
2、展开运算符和剩余参数:
- 展开运算符主要用于数组展开,在函数调用、数组字面量等场景使用;剩余参数在函数内部使用,用于获取多余实参。
- 语法上虽然都用...,但使用场景和目的不同。
当不确定传递多少个实参的时候,可以使用arguments动态参数或者剩余参数,从使用便利性和代码规范角度,优先考虑剩余参数。熟练掌握这三个特性,能帮助开发者编写出更灵活、高效的 JavaScript 代码。