什么是 [Arguments] 隐式参数?

这段时间总是看到有人提到 arguments 隐式参数, 并且在 方方老师 的面试经中也提到了这个词,但是好像很多人不知道怎么一回事。
确实在 ES6 普及之后,有了 ... 展开运算符之后就很少有用到 arguments 了,并且我在写这篇文章之前还总是拼错单词,因为我喜欢自己定义 parameter 形参…

arguments 是一个对应于传递给函数的参数的类数组对象(并不是 Array,除了 length 属性和索引元素之外没有任何 Array 属性)

arguments 对象是所有(非箭头)函数中都可用的局部变量。
你可以使用 arguments 对象在函数中引用函数的参数。此对象包含传递给函数的每个参数,第一个参数在索引 0 处。

使用方式

例如,如果一个函数传递了三个参数,你可以以如下方式引用他们:

1
2
3
4
5
6
7
8
9
function test() {
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
test(1, 2, 3);
// => 1
// => 2
// => 3

同样也可以进行赋值操作

1
2
3
arguments[1] = "new value";
console.log(arguments[1]);
// => new value

再重复一遍,arguments 不是数组它只能在函数内使用,
类似于 Array,但除了 length 属性和索引元素之外没有任何 Array 属性。
但是它可以被转换为一个真正的 Array:
上一组 demo

1
2
3
4
5
6
7
8
9
10
console.log(typeof arguments); // arguments 对象只能在函数内使用
function test() {
console.log(typeof arguments);
console.log(arguments[0]);
}
test(1);

// => undefined
// => object
// => 1

拓展 1

当然也可以通过以下方法转变成 Js 数组:

1
2
3
4
5
6
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES6
const args = Array.from(arguments);
const args = [...arguments];

拓展 2

在严格模式与非严格模式下进行赋值操作会出现不一样的结果

1
2
3
4
5
6
7
8
9
10
11
12
13
// 严格模式
function test(a) {
"use strict";
console.log(a, arguments[0]);
a = 50;
console.log(a, arguments[0]);
arguments[0] = 100;
console.log(a, arguments[0]);
}
test(10);
// => 10 10
// => 50 10
// => 50 100
1
2
3
4
5
6
7
8
9
10
11
12
// 非严格模式
function test(a) {
console.log(a, arguments[0]);
a = 50;
console.log(a, arguments[0]);
arguments[0] = 100;
console.log(a, arguments[0]);
}
test(10);
// => 10 10
// => 50 50
// => 100 100

当然这些看看就好

拓展 3

一些专业名词:

  • Parameters 函数显式参数 function test(parameter1, parameter2, parameter3)
  • Arguments 隐式参数 ( 我就不写伪代码了… )

参考资料