据我所知,这两个函数的行为方式相同:
function returnArgs() { return Array.prototype.slice.call(arguments) };
function returnArgs2() { return Array.apply(null, arguments) };
我看到这两种方法都在SO上引用,但仍然不能理解你为何使用其中一种方法。是偏好,还是有更实际的力量在起作用?也许我错过了一个明显的区别?
答案 0 :(得分:4)
第二个非常危险,并且永远不会工作。尝试:
console.log(returnArgs2(3));
这将显示一个长度为3的空数组.Array构造函数将单个数字参数解释为您想要一个具有该长度的数组。
编辑 - 作为更新,基于some interesting information about optimization,如果有"危险"事情就在这里"泄漏" arguments
个对象。根据那篇文章,将arguments
从函数中传递出来会使函数代码的分析变得非常困难,因为arguments
对象是如此奇怪。如果你想防止这种情况,安全的做法是:
function returnArgs() {
var rv = [];
for (var i = 0; i < arguments.length; ++i)
rv.push(arguments[i]);
return rv;
}
对arguments.length
的引用是可以的,对arguments
对象的属性的引用也是如此,这些对象是与实际参数对应的整数。令人遗憾的是,更漂亮的&#34;这样做的功能性方法击败了优化器,但这并不奇怪。
&#34;怪异的&#34;关于arguments
对象的事情是它为实际参数提供了别名。例如:
function foo(a, b) {
arguments[1] = a;
return b;
}
alert(foo("hello", "world")); // "hello"
对arguments[1]
的分配与对参数变量b
的直接分配具有完全相同的效果,反之亦然。因此,如果arguments
对象&#34;逃脱&#34;从函数中,静态分析代码不知道参数可能发生什么(基本上与局部变量相同),所以它只是放弃并留下要解释的函数。
请注意,优化程序文件是关于V8的,但代码分析的问题不依赖于运行时。 Nashorn是JDK 8中的新运行时,它有一种非常不同的优化方法,但我强烈怀疑滥用arguments
的净效果是相似的。