Array.prototype.slice.call(arguments)和Array的区别.应用(null,参数)
Difference between Array.prototype.slice.call(arguments) and Array.apply(null, arguments)
据我所知,这两个函数的行为是相同的:
function returnArgs() { return Array.prototype.slice.call(arguments) };
function returnArgs2() { return Array.apply(null, arguments) };
我看到这两种方法在SO中都被引用,但仍然不明白为什么要使用其中一种而不是另一种。是偏好,还是有更实际的因素在起作用?也许我忽略了一个明显的区别?
第二种方法非常危险,并不总是有效。试一试:
console.log(returnArgs2(3));
将显示一个长度为3的空数组。Array构造函数将单个数字参数解释为需要该长度的数组。
编辑本;作为更新,基于一些关于优化的有趣信息,如果这里有一个"危险"的事情,那就是arguments
对象的"泄漏"。根据那篇文章,从函数中传递arguments
会使函数代码的分析变得非常困难,因为arguments
对象非常奇怪。如果你想防止这种情况发生,安全的做法是:
function returnArgs() {
var rv = [];
for (var i = 0; i < arguments.length; ++i)
rv.push(arguments[i]);
return rv;
}
引用arguments.length
是可以的,引用arguments
对象的属性是与实际参数相对应的整数也是可以的。不幸的是,"更漂亮"的函数式方法打败了优化器,但这并不奇怪。
arguments
对象的"奇怪"之处在于它为实际参数提供了别名。例如:
function foo(a, b) {
arguments[1] = a;
return b;
}
alert(foo("hello", "world")); // "hello"
对arguments[1]
赋值与对参数变量b
直接赋值具有完全相同的效果,反之亦然。因此,如果arguments
对象从函数中"转义",静态分析代码不知道参数(本质上与局部变量相同)可能会发生什么,因此它只是放弃并让函数进行解释。
请注意,那篇优化器论文是关于V8的,但代码分析的问题与运行时无关。Nashorn, JDK 8中的新运行时,有一个非常不同的优化方法,但我强烈怀疑误用arguments
的净效果是相似的。
相关文章:
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- Emberjs应用程序加载在除Index之外的所有路由上
- 使用电话间隙在Android应用程序中显示SQL Lite的数据
- 跟踪在页面加载时应用内联样式的JavaScript
- 在AngularJS应用程序中使用封装指令和路由的推荐方式是什么
- 如何为json对象中的段发送array[]
- 如果文本字段为空,则使用JavaScript应用CSS样式
- Windows8应用程序(html&Javascript):从图片库(除了文件选择器)显示图像的另一种方式
- 为什么在单独的函数中应用时转换会闪烁/断断续续(D3)
- angular 1.5应用程序中的导航栏
- 在Web应用程序中使用Highcharts javascript
- angularjs+rails应用程序中未显示模板
- 从html创建一个指令,该指令按类名应用函数
- 使用acess代币登录Facebook,并通过网络应用程序离线发布
- 从HTTPGET返回一个自定义对象列表,以便在Angular 2应用程序中使用
- Javascript Array.indexOf() 在应用于对象数组时表现出奇怪的行为
- Array.prototype.push.应用意外行为
- 将JavaScript函数应用于除第i个元素之外的所有Array元素
- Array.prototype.slice.call(arguments)和Array的区别.应用(null,参数)