为什么当您试图修改javascript arguments对象时,它的行为如此奇怪
Why does the javascript arguments object behave so strangely when you try to modify it?
考虑以下内容:
foo打算接受arguments对象并重新排列顺序,将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环境中运行这个程序
arguments object
不是数组。它是一个内部类型为Arguments
的列表,具有length
属性和属性0
到len - 1
的getters/ssetters,其中len
是函数声明的参数数和调用函数的元素数中的较小者。一旦创建了此对象,当您对其属性进行操作时,系统将不会增加/减少length
,并且尝试将其设置为length
不会添加/删除键。属性0
到len - 1
的getter/setter实际上是函数中参数名称的别名(即,当您设置b = 1
时,您将看到arguments[1] === 1
)。
当foo
尝试设置args[2]
时,添加了一个整型属性,触发V8将底层数组存储调整为20个元素(它应该知道这是一个Arguments
类型,所以它可能会将其设置为哈希属性)。如果设置args[20] = 1
,则其大小将调整为47,args[100] = 1
将调整为167,但设置args[1026] = 1
将使其成为稀疏阵列(但首先设置args[1025] = 1
,然后设置args[2048]
不会使其稀疏),等等。
调整大小后,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的错误,尽管它非常尖锐。
- 使用AngularJS修改对象位置只需一次
- Reactjs:在修改对象之前,是否需要复制处于组件状态的对象
- 修改对象的原型不起作用
- 在 Javascript 中修改对象
- 通过Web服务修改对象列表,如何获取最终值列表
- 修改对象属性的方法中的 JavaScript 变量
- 在PouchDB/Barket.js中推送promise数组之前修改对象的值
- 就地修改对象javascript
- Backbone JS事件函数修改对象
- Javascript:从指针修改对象
- 使用Undercore在另一个对象内部修改对象内部的数组
- 修改对象's键而不创建新对象
- 在发布文档之前,如何在find()中修改对象级别的文档
- 在加载对象DOM之前修改对象DOM
- JS取回JSON解析是修改对象
- 继承和修改对象
- 在javascript中修改对象中的节点
- 修改对象存储的主键值
- 如何在修改对象后更新html中的数据
- Parse.com云功能-在发送到客户端之前手动修改对象字段