为什么javascript arguments对象在您试图修改它时表现得如此奇怪?
考虑以下几点: foo打算接受arguments对象并重新排列顺序,将arg1移动到arg2的位置为什么javascript arguments对象在您试图修改它时表现得如此奇怪?,javascript,arguments,Javascript,Arguments,考虑以下几点: foo打算接受arguments对象并重新排列顺序,将arg1移动到arg2的位置 function foo (args) { args[2] = args[1]; args[1] = undefined; } bar使用foo的参数调用foo function bar (a, b, c) { foo(arguments); console.log(arguments); } 我希望下面的结果类似于{0:'hello',1:undefined,
function foo (args) {
args[2] = args[1];
args[1] = undefined;
}
bar
使用foo的参数调用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环境中运行它不是数组。它是一个具有内部类型参数
的列表,具有长度
属性和属性的getter/setter0
到len-1
,其中len
是函数的声明参数数和调用函数的元素数中的较小者。创建此对象后,当您对其属性进行操作时,系统将不会增加/减少长度
,并且尝试将其设置为长度
不会添加/删除关键点。属性0
到len-1
的getter/setter实际上是函数中参数名称的别名(即,当设置b=1
时,您将看到参数[1]==1
)
当foo
尝试设置args[2]
时发生的情况是,添加了一个整型属性触发器V8,以将基础数组存储调整为20个元素(它应该知道这是一个参数
类型,因此可能可以将其设置为哈希属性)。如果您将args[20]=1
设置为47,args[100]=1
将调整为167,但设置args[1026]=1
将使其成为稀疏数组(但首先设置args[1025]=1
,然后args[2048]
不会使其稀疏),等等
调整大小后,Object.keys
将所有0
报告给19
作为属性,因此(哪个调用)只打印所有属性
(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错误,尽管它非常尖锐。这似乎是V8的一个问题,因为浏览器测试的“问题”只在Chrome中出现,而不使用Moz Spidermonkey。TBH,我认为对数组“参数”的直接操作是危险的,在开始使用它之前,最好使用一个拷贝“代码>数组.Trime.Studio。调用(参数)< /C>”。要清楚,<代码>参数< /C> >不是数组。它就像一个数组。应用数组期望值可能会导致意外的结果。@StickyCube我想知道您的用例可能是什么……如果您添加
“use strict”
到函数bar
它按预期工作。由于参数.length
是正确的,因此基于此的任何迭代都会得到所需的结果。在某种意义上,不是所有维度之外的索引都未定义吗?当然,在控制台中显示这些内容有点让人困惑,但它很难阻止显示。