考虑以下事项:
foo打算获取参数对象并重新排列顺序,将arg1移动到arg2的位置
function foo (args) {
args[2] = args[1];
args[1] = undefined;
}
bar
用它的参数调用foo
function bar (a, b, c) {
foo(arguments);
console.log(arguments);
}
我希望以下结果类似于{ 0: 'hello', 1: undefined, 2: 'world' }
bar('hello', 'world');
然而,我得到:
{
0: 'hello',
1: undefined,
2: 'world',
3: undefined,
4: undefined,
5: undefined,
6: undefined,
7: undefined,
8: undefined,
9: undefined,
10: undefined,
11: undefined,
12: undefined,
13: undefined,
14: undefined,
15: undefined,
16: undefined,
17: undefined,
18: undefined,
19: undefined
}
我完全不知道为什么会这样。 有人有什么想法吗?
我在node.js环境中运行它
答案 0 :(得分:3)
arguments object
不是数组。它是一个内部类型为Arguments
的列表,其中包含length
属性以及属性0
到len - 1
的getter / setter,其中len
是较小的length
函数的声明参数数量和调用函数的元素数量。创建此对象后,系统在操作其属性时不会增加/减少length
,并且尝试将其设置为0
不会添加/删除密钥。属性len - 1
到b = 1
的getter / setter确实是函数中参数名称的别名(即,当您设置arguments[1] === 1
时,您将看到foo
)。
args[2]
尝试设置Arguments
时发生的事情是添加一个整数属性会触发V8将底层数组存储大小调整为20个元素(它应该知道这是一个args[20] = 1
输入所以它可能会将其设置为哈希属性而不是)。如果您设置args[100] = 1
它将调整为47,args[1026] = 1
将调整为167,但设置args[1025] = 1
将使其成为稀疏数组(但首先设置args[2048]
然后{ {1}}不会使它稀疏)等等。
调整大小后,Object.keys
会将所有0
报告为19
作为属性,因此console.log
(调用util.format
)只打印所有这些属性。
(function (a, b, c) { (function (args) { args[2] = 1; })(arguments); console.log(Object.keys(arguments)); })("hello", "world")
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]
这绝对是一个V8错误,虽然它非常前卫。