我在various places中读到,谨慎对待arguments
对象,这是可行的......
var i = arguments.length, args = new Array(i);
while (i--) args[i] = arguments[i];
但是,这样可以吗?...
function makeArray (l) {
var i = l.length, array = new Array(i);
while (i--) array[i] = l[i];
return array;
};
//...
//EDIT: put the function on an object to better represent the actual case
var o = {};
o.f = function (callback) {
var args = makeArray (arguments);
callback.apply(args[0] = this, args);
};
"泄漏的论点是什么意思"以及它如何影响优化?
我专注于V8,但我认为它也适用于其他编译器?
证明它有效......
function makeArray (l) {
var i = l.length, array = new Array(i);
while (i--) array[i] = l[i];
return array;
};
//...
//EDIT: put the function on an object to better represent the actual case
var o = {};
o.f = function (callback) {
var args = makeArray (arguments);
callback.apply(args[0] = this, args);
};
o.m = "Hello, ";
function test(f, n) {
alert(this.m + " " + n)
}
o.f(test, "it works...")

答案 0 :(得分:8)
arguments
的问题与本地eval
和with
的问题相同:它们会导致别名。 Aliasing defeats all sorts of optimizations因此,即使您启用了这些函数的优化,您最终也可能只是浪费时间而这是JIT的一个问题,因为在编译器中花费的时间不是花费时间来运行代码(尽管优化中的一些步骤)管道可以并行运行。
由于arguments
泄漏导致的别名:
function bar(array) {
array[0] = 2;
}
function foo(a) {
a = 1;
bar(arguments);
// logs 2 even though a is local variable assigned to 1
console.log(a);
}
foo(1);
请注意,严格模式消除了这一点:
function bar(array) {
array[0] = 2;
}
function foo(a) {
"use strict";
a = 1;
bar(arguments);
// logs 1 as it should
console.log(a);
}
foo(1);
然而,严格模式也没有得到优化,我不知道任何合理的解释,除非基准测试不使用严格模式,很少使用严格模式。这可能会改变,因为许多es6功能需要严格模式,es6中不需要arguments
所以...
答案 1 :(得分:1)
这是一个双重问题:
arguments
对象无法预测。请考虑以下代码(运行风险自负!):
function a(){return arguments;}
x=a(document.getElementsByTagName('*'));
window._interval=setInterval(function(){
for(var i=0;i<1e6;i++)
{
x=a(x);
}
},5000);
&#13;
*{font-family:sans-serif;}
&#13;
<p>Warning! This may overheat your cpu and crash your browser really badly!</p>
<p>I'm not responsible for any software and hardware damages!</p>
<p><b>Run at your own risk!!!</b></p>
<p>If you ran this code, press F5 to stop or close the browser.</p>
<p>If you want, you can try to <button onclick="window.clearInterval(window._interval);window.x='';">stop it</button>. (the RAM may remain unchanged)</p>
&#13;
现在看着你的RAM上升,当你运行时(它每5秒钟以大约300-500MB的速度上升)。
简单地传递参数的简单实现可能会导致这些问题。
更不用说你的代码(通常)会慢一些。
请注意:
function a(){return arguments;}
function b(arg){return arg;}
x=a(document.getElementsByTagName('*'));
window._interval=setInterval(function(){
for(var i=0;i<1e6;i++)
{
x=b(x);
}
},5000);
&#13;
*{font-family:sans-serif;}
&#13;
<p>This may be safe, but be careful!</p>
<p>I'm not responsible for any software and hardware damages!</p>
<p><b>Run at your own risk!!!</b></p>
<p>If you ran this code, press F5 to stop or close the browser.</p>
<p>If you want, you can try to <button onclick="window.clearInterval(window._interval);window.x='';">stop it</button>.</p>
&#13;
不会产生与以前的代码相同的效果
这是因为b()
返回相同的变量,而不是对新arguments
对象的新引用
这是非常重要的区别。