【发布时间】:2015-11-03 12:32:04
【问题描述】:
我需要围绕其他函数创建包装函数。众所周知,arguments 对象非常古怪,不能逐字传递给任何函数。 V8 中的数组创建也不便宜。所以我能想到的最快的代码是这样的:
function wrap (fun) {
// reuse the same array object for each call
var args = [];
var prevLen = 0;
return function () {
// do some wrappy things here
// only set args.length if it changed (unlikely)
var l = arguments.length;
if (l != prevLen) {
prevLen = args.length = l;
}
// copy the args and run the functon
for (var i = 0; i < l; i++) {
args[i] = arguments[i];
}
fun.apply(this, args);
};
}
var test = wrap(function (rec) {
document.write(arguments[1] + '<br />');
if (rec) test(false, 'something else');
document.write(arguments[1] + '<br />');
});
test(true, 'something');
除非真的需要,否则我可以避免创建或更改数组对象的长度。性能提升相当严重。
问题:我在所有地方都使用相同的数组,并且在函数调用完成之前它可能会改变(参见示例)
问题: 传递给 .apply() 的数组是否被复制到 all JavaScript 实现中的其他地方?当前的 EcmaScript 规范是否保证第四行输出永远不会是 something else?
它在我检查过的所有浏览器中都可以正常工作,但我希望在这里能够适应未来。
【问题讨论】:
-
很大程度上取决于这些
// do some wrappy things here是什么。你能告诉我们你在那里做什么吗? -
你为什么要使用数组而不是
fun.apply(this, arguments)? -
@Bergi 1)我不做任何与参数相关的事情,但我认为这不重要 2)因为将“参数”作为参数传递给任何函数(甚至 .apply( )) 禁用 V8 中的优化(我认为其他地方也是如此)
-
这个 IEFE 完全没有必要顺便说一句,你已经有了一个函数作用域。
-
1) 好吧,如果它确实调用了一些用户提供的函数,那 可能会对您的 static-
args方法造成一些危害。 2) 不,将arguments传递给apply在V8 中非常好
标签: javascript arguments parameter-passing