4

So many times I see this following expression:

var args = [].slice.call(arguments, 0);

But [].slice.call([1,2,3,4,5], 0) is exactly [1,2,3,4,5].

And isn't it just saying

var args = arguments ?

So what exactly does [].slice do here?

Shih-Min Lee
  • 9,350
  • 7
  • 37
  • 67
  • It turns the function arguments into an array so you can use Array prototype methods on it. – Sebastian Simon Jun 29 '15 at 03:13
  • about the second part question. I see so many people doing `var args = [].slice.call(arguments, 0);` . Is there some advantage about this pattern instead of just using `var args = arguments`? – Shih-Min Lee Jun 29 '15 at 03:22
  • Read my comment above: it allows you to use Array prototype methods. You can’t `sort` an `arguments` object, you can’t `filter` an `arguments` object, you can’t `map` an `arguments` object. You can do so with an Array-`slice`d `arguments` object, though. – Sebastian Simon Jun 29 '15 at 03:25
  • So basically you're preping the arguments for future array methods right? Even though you haven't use it under this function scope but it give you future extensibility. Is my understanding correct? – Shih-Min Lee Jun 29 '15 at 03:35
  • Not sure whether I can interpret your use of the word “future” correctly; do you mean “later in the code” or “in the future when ES6 becomes standard”? The core of converting an `arguments` object to an Array is to use methods on it that only Array objects have. – Sebastian Simon Jun 29 '15 at 03:38
  • ya I mean later in the code.. – Shih-Min Lee Jun 29 '15 at 03:41
  • I just saw it's very common for document.querySelectorAll since this method returns a NodeList object. In that way: [].slice.call(document.querySelectorAll('whatever')) you get an Array object with all the fancy and cool methods. – Rudy Jun 14 '19 at 13:55

1 Answers1

5

slice is an array method which extracts subarrays from an array:

The slice method takes two arguments, start and end, and returns an array containing the elements of the array from element start up to, but not including, element end (or through the end of the array if end is undefined).

For example:

[0,1,2,3,4].slice(2);   // [2,3,4]
[0,1,2,3,4].slice(-2);  // [3,4]
[0,1,2,3,4].slice(2,4); // [2,3]
[0,1,2,3,4].slice();    // [0,1,2,3,4]

Specifically, both slice() and slice(0) produce a copy of the array. Then you will be able to alter the copy without affecting the original, and vice versa.

Additionaly, it can also be used with array-like objects:

The slice function is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

Therefore, it is often used to build a real array from an array-like object:

[].slice.call({0:0, 1:1, 2:2, length:3}); // [0,1,2]

Note this trick is no longer necessary in ECMAScript 6, because you can use Array.from:

Array.from({0:0, 1:1, 2:2, length:3}); // [0,1,2]

Having a real array instead of an array-like object has the advantage that you can use array methods on them.

Oriol
  • 274,082
  • 63
  • 437
  • 513