简体   繁体   中英

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. Array creation in V8 is not cheap either. 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? Is it guaranteed by the current EcmaScript spec that the fourth line of output will never ever be 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?

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.

According to the spec it is indeed supposed to be copied so the code seems to be safe.

Let argList be CreateListFromArrayLike(argArray).

Return Call(func, thisArg, argList).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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