Skip to content

Instantly share code, notes, and snippets.

@minitech
Created May 19, 2012 22:52
Show Gist options
  • Save minitech/2732683 to your computer and use it in GitHub Desktop.
Save minitech/2732683 to your computer and use it in GitHub Desktop.
Why you should use my new way to convert to an array
// The data
var items = document.getElementsByTagName('p');
// The old way
var arr = Array.prototype.slice.call(items);
// Pros:
// - Doesn't need a helper method that loops through stuff
//
// Cons:
// - Verbose
// - Doesn't work in IE 8 or lower
// The new way
var arr = Array.apply([], items);
// Pros:
// - Doesn't need a helper method that loops through stuff
// - Reasonably concise
// - Works in IE 7 and 8 at least
//
// Cons:
// - None that I can think of! Take that, old way! (jsPerf test pending.)
// Awesome new way brought to you by Ryan O'Hara (minitech)
@florian
Copy link

florian commented May 20, 2012

@pimvdb This doesn't have anything to do with arguments I think, it's just the way Array works.

Array(1, 2); // [1, 2]
Array(1); // [,] – Returns an array with the length of one, not [1]
// To make this more clear:
Array(5).length; // 5 – not 1 as you might expect.

Pretty weird, but it can be useful in a few situations (underscore.js makes use of it).


Are you sure the old way doesn't work in IE? Unfortunately I'm not able test it on Linux.

@pimvdb
Copy link

pimvdb commented May 20, 2012

@js-coder: That's what I meant. For NodeLists the behaviour of Array does not matter because they never consist of a number, but for arguments it does matter in case you pass a number as the only argument to the function.

Array.prototype.slice throws an error complaining about the type of this in IE8.

@florian
Copy link

florian commented May 20, 2012

@pimvdb Oh, that's true. Array.apply([], document.getElementById('id')) returns an empty array for me though.
I expected it to return an array containing the DOM node.

Edit: Array.prototype.slice.call(document.getElementById('id')) returns an empty array, too.

@pimvdb
Copy link

pimvdb commented May 20, 2012

@js-coder: .apply expects an array, so:

Array.apply([], [ document.getElementById('id') ]);

But since getElementById returns at most one element, the whole .apply trick is not necessary I think. You could just do [ elem ] to put the element in an array. As I understand it, the gist is about converting an array-like object to a real array, which is a problem you don't encounter with getElementById.

@florian
Copy link

florian commented May 20, 2012

@pimvdb Yeah, I had an error in reasoning. :)


[].slice.call(items); seems to work, too, and it's a bit shorter than the usual way. (It creates a new array though, but I don't think you'll see any real performance difference.)

@minitech
Copy link
Author

Argh. Right. And yes, null is better, [] is left over from other experiments.

@js-coder: Still doesn't work in IE, though - that's what I'm trying to fix in a non-frustrating way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment