我试图将一个 arguments
对象与另一个数组连接起来,我写了这样的代码:
[].concat.call(arguments, newArray)
但它返回 [ [object Arguments], ... ]
,这完全不是我想要的。我用谷歌搜索并找到了一些关于为什么我可以通过切片方法做到这一点的解释:How can I convert the "arguments" object to an array in JavaScript?
但在查阅规范后,我发现 concat 方法有相同的定义:
NOTE The
concat
function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method. Whether theconcat
function can be applied successfully to a host object is implementation-dependent.
规范在这里:http://es5.github.io/#x15.4.4.4
所以现在我很困惑为什么我不能通过concat
方法将arguments
对象转换成数组。
最佳答案
详情请见§15.4.4.4 of the spec .基本上,它从创建要处理的事物列表开始,其中列表中的第一项是您调用它的对象 (this
),然后列表中的后续项是功能。然后循环遍历列表并处理每个项目。对于该列表中不是数组的项目,它有一个明确的分支,该分支的“其他”是(步骤 5(c)):
- 否则,E 不是数组
- 使用参数 ToString(n) 调用 A 的 [[DefineOwnProperty]] 内部方法,属性描述符 {[[Value]]: E, [[Writable]]: true, [[Enumerable]]: true, [[可配置]]:true}和false。
- 将 n 增加 1。
因此您可以在非数组上调用concat
。它不会失败。但它不会将非数组类数组的事物视为数组。
备注Felix's observation这种“只有数组才能展开它们的条目”在 ES6 中正在发生变化。 concat
使用新的 "is concat
spreadable" flag在对象上确定它是否应该循环遍历它们的条目。不过,我认为 arguments
对象不会有那个标志(至少,我在 §9.4.4 中没有看到任何这样的说法),可能是为了避免向后兼容性问题。
关于javascript - 为什么我不能在 JavaScript 中使用 concat 方法将 "argument"对象转换为数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29446528/