arguments详解

特性

  • 类数组
  • 没有继承 Array.prototype
  • 可迭代
  • 箭头函数内部没有 arguments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* callee: 宿主函数 test
* Symbol.iterator 可迭代对象标志
*
* 类数组 Array like
* 有 length 从 0 开始的属性下标
* 没有数组的内置方法(build-in methods/object)
*
*/
function test() {
console.log(arguments);
console.log(arguments.toString()); // [object Arguments]
console.log(Array.isArray(arguments)); // false
console.log(arguments.callee);
}

test();

可迭代对象

普通对象没有迭代器无法迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var obj = {
a: 1,
b: 2,
c: 3
}

function * generator(args) {
for (const item of args) {
yield item;
}
}

var it = generator(obj);

it.next();

🌈 arguments可以迭代

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function * generator(args) {
for (const item of args) {
yield item;
}
}

function test() {
var it = generator(arguments);

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
}

test(1, 2, 3);

非箭头函数的其他函数的内置的局部变量

1
2
3
4
var test = () => {
console.log(arguments);
}
test();

改用剩余参数:

1
2
3
4
5
var test = (...args) => {
console.log(args);
console.log(Array.isArray(args));
}
test(1, 2, 3);
1
2
3
4
5
var test = (...args) => {
// console.log(arguments.callee); // 直接拿 test 能拿到,不需要 .callee
console.log(test);
}
test(1, 2, 3);

arguments 转真数组

1
2
3
4
5
6
7
function test() {
// var params = Array.prototype.slice.call(arguments); // ↓简便写法
var params = [].slice.call(arguments); // 把 arguments 当 [] 去调用 slice
console.log(params);
}

test(1, 2, 3);
1
2
3
4
5
6
7
8
function test() {
var params = arguments.length === 1
? [arguments[0]]
: Array.apply(null, arguments); // Array是构造函数,传递null当this,参数是arguments
console.log(params);
}

test(1, 2, 3);

arguments作用

拿到实参 - 实参个数 > 形参个数

1
2
3
4
function test(a, b, c) {
console.log(arguments[3]);
}
test(1, 2, 3, 4);

不定参数

1
2
3
4
5
6
function add() {
return [...arguments].reduce((pre, cur) => pre + cur, 0);
}

const res = add(1, 2, 3);
console.log(res);

🌈 形实参的对应关系 - 共享关系

形参赋值的有内部作用域

形实参默认情况下会有共享关系

1
2
3
4
5
6
function test(a) {
arguments[0] = 10;
console.log(a, arguments[0]);
}

test(1);
1
2
3
4
5
6
function test(a) {
a = 10;
console.log(a, arguments[0]);
}

test(1);

🌈 形参 - 只要有一个形参有默认值,arguments就不跟踪形参

1
2
3
4
5
function test(a = 100) {
arguments[0] = 10;
console.log(a, arguments[0]);
}
test(1);
1
2
3
4
5
function test(a = 100) {
a = 10000;
console.log(a, arguments[0]);
}
test(1);
1
2
3
4
5
6
7
8
9
10
function test(a, b, c = 10) {
arguments[0] = 100;
arguments[1] = 200;
arguments[2] = 300;

console.log(a, arguments[0]);
console.log(b, arguments[1]);
console.log(c, arguments[2]);
}
test(1, 2, 3);

🌈 形参 - 剩余参数,arguments不跟踪

1
2
3
4
5
6
7
8
9
10
function test(...args) {
arguments[0] = 100;
arguments[1] = 200;
arguments[2] = 300;

console.log(args[0], arguments[0]);
console.log(args[1], arguments[1]);
console.log(args[2], arguments[2]);
}
test(1, 2, 3);

🌈 形参 - 参数解构,arguments不跟踪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function test({ a, b, c }) {
arguments[0] = 100;
arguments[1] = 200;
arguments[2] = 300;

console.log(a, arguments[0]);
console.log(b, arguments[1]);
console.log(c, arguments[2]);
}
test({
a: 1,
b: 2,
c: 3
});

🌈 严格模式下 - arguments不跟踪

1
2
3
4
5
6
7
8
9
10
11
function test(a, b, c) {
'use strict';

a = 10;
b = 20;
c = 30;

console.log(a, b, c);
console.log([...arguments]);
}
test(1, 2, 3);
1
2
3
4
5
6
7
8
9
10
11
function test(a, b, c) {
'use strict';

arguments[0] = 10;
arguments[1] = 20;
arguments[2] = 30;

console.log(a, b, c);
console.log([...arguments]);
}
test(1, 2, 3);

拓展

内置方法/对象 or 内部方法

  • 内置方法、对象:build-in methods/object
  • 内部方法:internal methods