Difference between Array.prototype.slice.call(arguments) and Array.apply(null, arguments)

StackOverflow https://stackoverflow.com/questions/23662764

  •  22-07-2023
  •  | 
  •  

Question

As far as I can tell, these two functions behave the same way:

function returnArgs() { return Array.prototype.slice.call(arguments) };

function returnArgs2() { return Array.apply(null, arguments) };

I see both approaches referenced all over SO, but still don't really understand why you'd use one over the other. Is it preference, or are there more practical forces at play? Perhaps I'm missing an obvious difference?

Was it helpful?

Solution

The second one is pretty dangerous and won't always work. Try:

console.log(returnArgs2(3));

That'll show an empty array of length 3. The Array constructor interprets a single numeric argument as meaning you want an array of that length.

edit — as an update, based on some interesting information about optimization, if there's a "dangerous" thing here it's that "leaking" of the arguments object. According to that article, passing arguments out of a function makes analysis of the function's code really hard, because the arguments object is so weird. If you want to prevent that, the safe thing to do is:

function returnArgs() {
  var rv = [];
  for (var i = 0; i < arguments.length; ++i)
    rv.push(arguments[i]);
  return rv;
}

References to arguments.length are OK, as are references to properties of the arguments object that are integers corresponding with actual arguments. It's unfortunate that the "prettier" functional ways of doing this defeat the optimizer, but it's not really surprising.

The "weird" thing about the arguments object is that it provides aliases for actual arguments. For example:

function foo(a, b) {
  arguments[1] = a;
  return b;
}

alert(foo("hello", "world")); // "hello"

That assignment to arguments[1] has exactly the same effect as a direct assignment to the parameter variable b, and vice-versa. Thus if the arguments object "escapes" from a function, the static analysis code has no clue what may happen to the parameters (which are essentially the same as local variables), so it kind-of just gives up and leaves the function to be interpreted.

Note that that optimizer paper is about V8, but the problems of code analysis are not runtime-dependent. Nashorn, the new runtime in JDK 8, has a much different optimization approach, but I strongly suspect the net effect of misusing arguments are similar.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top