why `splice.apply(arguments, 0)` fails while `splice.call(arguments, 0)` returns Array
我试图将函数内部可访问的arguments变量转换为数组。我试过两种方法:
1 2
| Array.prototype.splice.apply(arguments, 0) //fails
Array.prototype.splice.call(arguments, 0) //return array |
你们能详细说明为什么第一个选择失败,而第二个选择成功吗?
- .apply()的第二个参数应该是一个数组,就像[0]一样。
- 实际上,这就是call和apply之间的主要区别。
- 事实上,Array.prototype.splice.apply(arguments, [0])应该是有效的。apply()和call()不一样!
- 错误信息Function.prototype.apply: argumentsArray is not an array-like object应该足够清楚,或者至少告诉您检查文档。
- 因为ecma international.org/ecma-262/5.1/sec-15.3.4.3
- @尖刻的,谢谢,你能让你的评论成为一个答案,这样我就把它标记为答案吗?
这是因为Array.prototype.splice.apply(arguments, 0)大致相当于arguments.splice([0])strike>,正如我之前的其他人所说,apply期望数组作为其第二个参数。如果要检索n-first参数,可以执行Array.prototype.splice.apply(arguments, [0,n]),它(大致)相当于arguments.splice.(0,n)。
相反,call使用任何类型的参数。Array.prototype.splice.call(arguments, 0)大致相当于arguments.splice(0),由于splice期望一个整数作为其第一个参数而不是数组,所以第二个解决方案(但不是第一个解决方案)工作。因此,埃多克斯1〔9〕也可以像杰罗·诺顿所说的那样发挥作用。
请注意,我所指的"等价物"实际上不起作用,因为arguments不是一个数组,而是一个类似数组的对象。
但是,您提到的技术经常用于将类似数组的对象转换为适当的数组。
编辑:我编辑了我的答案,因为它包含了一个大错误。感谢库克怪兽的纠正。
- 你读过我写的东西吗?面向对象
- 是的。缺乏等价性与arguments是数组形式无关。
- 正如库奇埃蒙斯所说,不是江户一号〔1〕失败了。
- 哦,天哪,你说得对@cookiemonster.道歉。我会编辑我的答案。
- 嗯,你确定吗?我刚试过jsFiddle,得到了"typeerror:arguments.splice不是函数"。
- 啊,我错过了你的意思。我以为你指的是前者(.call,.apply)作为等价物。对于直接调用,该方法需要直接放置在arguments对象上。
- 啊。不,我只是想说,由于arguments是一个类似数组的对象,所以我们必须使用Array.prototype.call|apply(arguments,...)语法将其转换为一个适当的数组。但你是对的,这种技术是可能的,因为arguments是一个类似数组的对象。我希望现在一切都清楚了:)
- @瓦多杰弗斯:是的,+1