简体   繁体   English

重用传递给.apply()的数组是否安全?

[英]Is it safe to reuse the array passed to .apply()?

I need to create wrapper functions around other functions. 我需要围绕其他功能创建包装器功能。 It is well known that arguments object is quite cranky and can't be passed to any function verbatim. 众所周知,arguments对象是很奇怪的,不能逐字传递给任何函数。 Array creation in V8 is not cheap either. 在V8中创建数组也不便宜。 So the fastest code I could come up with is this: 因此,我能想到的最快的代码是:

 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'); 

This way I avoid creating or changing length of the array object unless really needed. 这样,除非确实需要,否则避免创建或更改数组对象的长度。 The performance gain is quite serious. 性能提升非常严重。

The problem: I use the same array all over the place and it could change before the function call is finished (see example) 问题:我到处使用相同的数组,并且在函数调用完成之前它可能会发生变化(请参见示例)

The question: is the array passed to .apply() copied to somewhere else in all JavaScript implementations? 问题:传递给.apply()的数组是否已复制到所有 JavaScript实现中的其他位置? Is it guaranteed by the current EcmaScript spec that the fourth line of output will never ever be something else ? 当前的EcmaScript规范是否保证输出的第四行永远不会是something else

It works fine in all the browsers I checked, but I want to be future-proof here. 它在我检查过的所有浏览器中都可以正常工作,但我想在这里适应未来的发展。

Is the array passed to .apply() copied to somewhere else, and is it guaranteed by the current EcmaScript spec? 传递给.apply()的数组是否已复制到其他地方,并且当前的EcmaScript规范可以保证吗?

Yes. 是。 The apply method does convert the array (or whatever you pass in) to a separate arguments list using CreateListFromArrayLike , which is then passed around and from which the arguments object for the call is created as well as the parameters are set. apply方法确实使用CreateListFromArrayLike将数组(或您传入的任何对象)转换为单独的参数列表,然后将其传递,并从中创建调用的arguments对象以及设置参数。

According to the spec it is indeed supposed to be copied so the code seems to be safe. 根据规范 ,确实应该将其复制,因此代码似乎是安全的。

Let argList be CreateListFromArrayLike(argArray). 令argList为CreateListFromArrayLike(argArray)。

Return Call(func, thisArg, argList). 返回Call(func,thisArg,argList)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM