简体   繁体   中英

array.unshift invoked using apply() causes “Maximum call stack size exceeded”

This code:

var arr = [];
arr.unshift.apply(arr, new Array(200000));

causes: Uncaught RangeError: Maximum call stack size exceeded (see http://jsfiddle.net/BnLxf/1/ )

While this code works fine:

var arr = [];
arr.unshift(new Array(200000));

Any idea why this happens?

Your first example is equivalent to this:

 arr.unshift(undefined, undefined, undefined, /* undefined 199,997 more times */);

Your second example just passes unshift one argument, which is an array with no entries and a length of 200000 .

This is because the purpose of Function#apply is to call a function with a given this value of arguments which are then then passed onto the target function as discrete (individual) arguments.

It's not entirely surprising that a JavaScript engine chokes when asked to call a function with 200,000 discrete arguments. (I also wouldn't have been surprised if it worked.)

If you want to pass the array as just a single argument, but you want to use something apply -like, use call :

arr.unshift.call(arr, new Array(200000));

call passes on the arguments you give it exactly as you give it to them (except the first one, which is what to use as this during the call).

The Function#apply method expects an array as 2nd parameter. You should embrace new Array(200000) with brackets:

var arr = [];
arr.unshift.apply(arr, [new Array(200000)]);

As Chris said, you can also call method .call instead of .apply :

var arr = [];
arr.unshift.call(arr, new Array(200000));

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