Javascript - Array

| Comments

Array Manipulation

Insert an item into an existing array is a daily common task. You can add elements to the end of an array using push, to the beginning using unshift, or the middle using splice.

But those are known methods, doesn’t mean there isn’t a more performant way [or] maybe a faster way.

Add to end of an array
Add a element at the end of the array is easy with push(), but there is a way more performant.

1
2
3
4
var arr = [1,2,3,4,5];

arr.push(6);
arr[arr.length] = 6; // 43% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1

Both methods modify the original array. Don’t believe me? Check the jsperf

Add to beginning of an array
Now we are trying to add a item to the beginning of the array

1
2
3
4
var arr = [1,2,3,4,5];

arr.unshift(0);
[0].concat(arr); // 98% faster in Chrome 47.0.2526.106 on Mac OS X 10.11.1

Here is a little bit detail, unshift edit the original array, concat return a new array. jsperf

Add to middle of an array
Add items at the middle of an array is easy with splice and is the most performant way to do it.

1
2
var items = ['one', 'two', 'three', 'four'];
items.splice(items.length / 2, 0, 'hello');

Tried to run these tests in various Browsers and OS and the results were similar.

Next time you write you code don’t just check for the best way of writing your code but also write code which runs faster to improve performance.

Convert Nodelist to Array

The querySelectorAll method returns an array-like object called a node list. These data structures are referred to as “Array-like”, because they appear as an array, but can not be used with array methods like map and foreach.

Here’s a quick, safe, and reusable way to convert a node list into an Array of DOM elements:

1
2
3
4
5
6
7
8
const nodeList = document.querySelectorAll('div');
const nodeListToArray = Array.apply(null, nodeList);

//later on ..

nodeListToArray.forEach(...);
nodeListToArray.map(...);
nodeListToArray.slice(...);

The apply method is used to pass an array of arguments to a function with a given this value. MDN states that apply will take an array like object, which is exactly what querySelectorAll returns. Since we don’t need to specify a value for this in the context of the function, we pass in null or 0. The result is an actual array of DOM elements which contains all of the available array methods.

Alternate method if you are using ES2015 you can use the spread operator ...

1
2
3
4
5
6
7
const nodeList = [...document.querySelectorAll('div')]; // returns a real Array

//later on ..

nodeList.forEach(...);
nodeList.map(...);
nodeList.slice(...);

Empty an Array

You define an array and want to empty its contents. Usually, you would do it like this:

1
2
3
4
5
6
7
// define Array
var list = [1, 2, 3, 4];
function empty() {
    //empty your array
    list = [];
}
empty();

But there is another way to empty an array that is more performant.

You should use code like this:

1
2
3
4
5
6
var list = [1, 2, 3, 4];
function empty() {
    //empty your array
    list.length = 0;
}
empty();
  • list = [] assigns a reference to a new array to a variable, while any other references are unaffected. which means that references to the contents of the previous array are still kept in memory, leading to memory leaks.

  • list.length = 0 deletes everything in the array, which does hit other references.

In other words, if you have two references to the same array (a = [1,2,3]; a2 = a;), and you delete the array’s contents using list.length = 0, both references (a and a2) will now point to the same empty array. (So don’t use this technique if you don’t want a2 to hold an empty array!)

Think about what this will output:

1
2
3
4
5
6
7
8
9
var foo = [1,2,3];
var bar = [1,2,3];
var foo2 = foo;
var bar2 = bar;
foo = [];
bar.length = 0;
console.log(foo, bar, foo2, bar2);

// [] [] [1, 2, 3] []

Stackoverflow more detail: difference-between-array-length-0-and-array

Comments