话不多说,先上面试题,如下:
function b(x, y, a) {
a = 8;
arguments[2] = 10;
console.log(a);
}
b(1, 2, 3);
大胆的我,直接就写会输出8。
然后就被质疑了一顿。
面试结束之后一段时间百度发现。
arguments对象很厉害,修改arguments会影响到函数的形参。如果进行删除arguments某一个参数,函数的形参也会进行变化,比如下面:
function b(x, y, a) {
a = 8;
console.log(arguments); // [1, 2, 8]
arguments[2] = 10;
console.log("-----------");
console.log(arguments); // [1, 2, 10]
console.log(a); // 10
// 删除
[].shift.call(arguments); // 删除arguments第一个参数
console.log("-----------");
console.log(arguments); // [2, 10]
console.log(x, y, a); // 2, 10, 10
// 修改arguments第二个参数
arguments[1] = 20
console.log("-----------");
console.log(arguments); // [2, 20]
console.log(x, y, a); // 2, 20, 10
// 新增两个元素
arguments[2] = 22
arguments[3] = 33
arguments.length = 4
console.log("-----------");
console.log(arguments); // [2, 20, 22, 33]
console.log(x, y, a); // 2, 20, 10
}
b(1, 2, 3);
由上面代码可以看出。再修改arguments的时候,形参的值也会修改。第一次删除数据的时候,函数最后一个形参的值直接变成arguments最后一个的值,而且后面修改跟添加都不会影响最后一个形参的值。
建议不要直接修改arguments,需要的话可以是用
[].slice.call(arguments)创建新的数组然后进行修改。
关于arguments
arguments是一个类数组的对象,要是用数组的方法需要 [].shift.call(arguments)来操作。
arguments还有callee,它的值是当前执行函数,可以用来函数进行内部递归。
function a (index) {
arguments[0]--
if (arguments[0] <= 0) {
return arguments[0]
} else {
arguments.callee(index)
// ...other code
}
}
a(10)
总结
- arguments的修改,函数形参的值也会修改;
- 不要直接修改arguments,会造成想不到的bug; 如果有补充或者错误的,请不吝指点~