Iterating over properties in objects. JQuery - Iterating over array, object and elements Js iterating


12 Mar 2016

In modern JavaScript, there are so-called “iteration methods” that are used to iterate through arrays. In this tutorial we will cover the following methods:

forEach

The .forEach() method is used for brute force array. It calls the so-called callback function, with the help of which three parameters item, i, arr are passed, where:

  • item — array element;
  • i is the serial number of the array;
  • arr is the array itself that should be iterated.

To make it easier to understand how to use this method, consider an example:

Var user=["admin","pass",31]; user.forEach(function(item,i,user)( alert("Value of item No. " + i + " : " + item); ));

This method can be used instead of a regular for loop.

filter

The .filter() method is used for filtering, it also uses the callback function, but creates a new array if the elements in the array match the value true:

Var arr=; var newArr=arr.filter(function(number)( return number< 0; }); alert(newArr); // выведет -34,-4

In this example, numbers are checked for negative values, and the output is a new array with these values. You can come up with your own conditions; these do not necessarily have to be numbers.

every/some

These two methods are similar to each other and both are used to check an array, only the method .every() returns true if all values ​​in the array match the specified condition, and the method .some() returns true if at least one value matches the condition:

Var arr=; alert(arr.every(function(number)( return number< 0; })); // выведет false

I hope it is clear that if in the example above we used some method then we would have displayed the value true instead of false.

map

The .map() method transforms the array and gets a new one from it. Everything is done by calling the callback function:

Var arr=; var newArr=arr.map(function(number)( return number*2; )); alert(newArr);

In this example, we received a new array with double the values ​​of the elements.

reduce/reduceRight

The last methods we will look at are reduce and reduceRight. They are used to process each element of the array while saving the intermediate result. The method iterates through each element from left to right, reduceRight does the opposite. Unlike other methods, in addition to the callback function, the initialValue argument is also specified here - “initial value”. Plus, the callback function specifies the “intermediate result” - previousValue And currentItem— current element of the array.

Let's look at an example:

Function getSums(arr) ( var result = ; if (!arr.length) return result; var totalSum = arr.reduceRight(function(sum, item) ( result.push(sum); return sum + item; )); result .push(totalSum); return result; ) alert(getSums()); // 1,3,6,10,15

What happened in this example? We have created a function that allows us to get a new array with elements created from the sum of the previous ones. Moreover, the report of elements comes from the end. And here is a simpler example in which I created a function that calculates the sum of elements in an array:

Function getSum(arr) ( var result = arr.reduce(function(sum, current) ( return sum + current )); return result; ); alert(getSum()); Tags: 

Hello! We continue to study array methods and in this lesson we will look at methods for iterating over an array. These methods allow you to traverse an array and perform certain actions on its elements. Yes, I forgot to say that all these methods are not supported in IE 8. Although it is so important now that they are not supported by this browser, but still, if you want IE8 support, then ES5-shim will help you. And we will continue

forEach method

This method is used to traverse an array in a loop, but you can pass it a function in which you can perform certain actions on the elements of the array. Let's look at an example.

Var mas = ["Banana", "Avocado", "Carrot"]; mas.forEach(function(item, i, mas) ( alert(i + ": " + item + " (array: " + mas + ")"); ));

Here in the example, a function is passed to the forEach method, which specifies 3 parameters:

item- array element

i— array element number

mas— the array that is being processed.

This method can be used instead of a for loop to iterate through an array.

filter method

This method, like the forEach method, is used to iterate through an array and is passed a function as an argument, but it allows you to filter the array and returns a new array, which contains only those elements for which the function that we pass to this method will return true.

It's a little confusing, so let's look at it with an example.

Var mas = ; var positiveNum = mas.filter(function(num) ( return num > 0; )); document.write(positiveNum); // 1,4,3

In the example there is an array with numbers and we need to get another array that would contain only positive numbers from the original array. To do this, we apply the filter method to the array and call a function that will check each element, that is, it will return all positive numbers, and the result will be stored in another array, in the example this is positiveNum.

map method

The map method creates another array, which will consist of the results of calling the function of the original array, but in this function some actions will take place on the elements of the original array and the result will appear in the new array as is. Let's look at an example, otherwise I think it's completely unclear.

Var mas = ; var newMas = mas.map(function(item) ( return item*item; )); // got an array with squares alert(newMas); // 1,4,9

In the example, there is an initial array with numbers, the map method is applied to it, in which each element of the array is multiplied by itself and the result is written to another array. As a result, we get an array with the squares of the numbers in the original array.

Methods every/some

These methods check whether an element is present in the array. They do this through a function that is passed to them as a parameter, that is, if this function returns true then the method itself will return true. Moreover, the every method requires that each element meet the condition of the function, and the some method requires that at least one match. And as always, here's an example for you.

Var mas = ; function isPositiv(num) ( return num > 0; ) if(mas.every(isPositiv)) ( document.write("The array contains only positive numbers"); ) else( document.write("The array contains at least one negative number "); ) if(mas.some(isPositiv)) ( document.write("The array contains at least one positive number"); ) else ( document.write("There are no positive numbers in the array"); )

Consider an example: we have an array with positive and negative numbers and we need to check it for the presence of at least one negative number. To do this, we use the every and some methods. We create a function that will return positive numbers and then pass it to the every method. Since this method returns a logical result, it is used in conditional statements. The every method in our example will return false because there are negative numbers in the array, but the some method will return true because there is at least one positive number in the array.

reduce/reduceRight

If you need to iterate through an array, you can use forEach, for or for..of.

If you need to iterate through an array and return data for each element, you use map.

Methods arr.reduce And arr.reduceRight Similar to the methods above, but they are a little more complicated. They are used to calculate a single value based on the entire array.

Syntax:

Let value = arr.reduce(function(previousValue, item, index, array) ( // ... ), );

The function is applied in turn to all elements of the array and “carries over” its result to the next call.

Arguments:

  • previousValue – the result of the previous call of this function, equal to initial on the first call (if initial is passed),
  • item – the next element of the array,
  • index – its index,
  • array – the array itself.

When a function is called, the result of its call on the previous element of the array is passed as the first argument.

This sounds complicated, but it becomes simpler if you think of the first argument as “accumulating” the result of previous function calls. When finished, it becomes the result of reduce.

This method is easiest to understand, as always, with an example.

Here we get the sum of all array elements in just one line:

Let arr = ; let result = arr.reduce((sum, current) => sum + current, 0); alert(result); // 15

Here we used the most common reduce option, which uses only 2 arguments.

Let's take a closer look at how it works.

  1. On the first run, sum is initial (the last argument of reduce), which is 0, and current is the first element of the array, which is 1. Thus, the result of the function is 1.
  2. The second time we run sum = 1, we add the second element of the array (2) to it.
  3. On the third run, sum = 3, to which we add the next element, and so on...

The computation flow looks like this:

In the form of a table, where each line is a function call on the next element of the array:

sum current result
first call 1 1
second call 1 2 3
third challenge 3 3 6
fourth challenge 6 4 10
fifth challenge 10 5 15

Here you can clearly see how the result of the previous call is passed into the first argument of the next one.

We can also omit the initial value:

Let arr = ; // the initial value is removed (no 0 at the end) let result = arr.reduce((sum, current) => sum + current); alert(result); // 15

The result is exactly the same! This is because in the absence of initial, the first element of the array is taken as the 1st value, and the search starts from the second.

The calculation table will be the same minus the first line.

But such use requires extreme caution. If the array is empty, calling reduce without an initial value will throw an error.

Here's an example:

Let arr = ; // Error: Reduce of empty array with no initial value // if there was an initial value, reduce would return it for an empty array. arr.reduce((sum, current) => sum + current);

Results

So, to summarize, we looked at various methods for working with arrays in a loop. All these methods have one thing in common, which is that they all need to pass a function as an argument.

  • forEach – for looping through an array.
  • filter – to filter the array. Returns a new filtered array
  • every/some – to check the array for the presence of individual elements.
  • map - to convert an array to an array. Returns the original converted array.
  • reduce/reduceRight - Computes one value from the entire array, calling a function on each element and passing the intermediate result between calls. Can be used to calculate the sum of array elements.

Tasks

Get a new array

Let the array var mas = ["HTML", "CSS", "JavaScript", "Pascal"] be given, you need to use the map method to get a new array that will contain the lengths of each element of the original array.

Filter the array

There is an array var mas = you need to use the filter method to get an array that contains only positive numbers.

Check array

There is an array var mas = you need to check if there are negative numbers in the array and display the result on the screen.

Well, in conclusion, a short video on methods for looping through an array.

  • Translation
  • I. Iterating over real arrays
    1. forEach method and related methods
    2. for loop
    3. Proper use of the for...in loop
    4. for...of loop (implicit use of iterator)
    5. Explicit use of iterator
    1. Using methods to iterate over real arrays
    2. Convert to a real array
    3. A note on runtime objects

I. Iterating over real arrays

At the moment, there are three ways to iterate over the elements of a real array:
  1. method Array.prototype.forEach ;
  2. classic for loop
  3. a “correctly” constructed for...in loop.
In addition, soon, with the advent of the new ECMAScript 6 (ES 6) standard, two more methods are expected:
  1. for...of loop (implicit use of iterator);
  2. explicit use of iterator.

1. The forEach method and related methods

If your project is designed to support the features of the ECMAScript 5 (ES5) standard, you can use one of its innovations - the forEach method.

Usage example:
var a = ["a", "b", "c"]; a.forEach(function(entry) ( console.log(entry); ));
In general, using forEach requires connecting the es5-shim emulation library for browsers that do not natively support this method. These include IE 8 and earlier, which are still in use in some places.

The advantage of forEach is that there is no need to declare local variables to store the index and value of the current array element, since they are automatically passed to the callback function as arguments.

If you're worried about the possible cost of calling a callback on each element, don't worry and read this.

ForEach is designed to iterate over all elements of an array, but in addition to it, ES5 offers several more useful methods for iterating through all or some elements plus performing some actions on them:

  • every - returns true if for each element of the array the callback returns a value that can be converted to true .
  • some - returns true if for at least one element of the array the callback returns a value that can be converted to true.
  • filter - creates a new array that includes those elements of the original array for which the callback returns true .
  • map - creates a new array consisting of the values ​​returned by the callback.
  • reduce - reduces an array to a single value, applying a callback to each element of the array in turn, starting with the first (can be useful for calculating the sum of array elements and other summary functions).
  • reduceRight - works similar to reduce, but iterates through elements in reverse order.

2. For loop

Good old for rules:

Var a = ["a", "b", "c"]; var index; for (index = 0; index< a.length; ++index) { console.log(a); }
If the length of the array is constant throughout the loop, and the loop itself belongs to a performance-critical section of code (which is unlikely), then you can use a “more optimal” version of for that stores the length of the array:

Var a = ["a", "b", "c"]; var index, len; for (index = 0, len = a.length; index< len; ++index) { console.log(a); }
In theory, this code should run a little faster than the previous one.

If the order of the elements is not important, then you can go even further in terms of optimization and get rid of the variable for storing the length of the array, changing the order of the search to the reverse:

Var a = ["a", "b", "c"]; var index; for (index = a.length - 1; index >= 0; --index) ( console.log(a); )
However, in modern JavaScript engines such optimization games usually mean nothing.

3. Correct use of the for...in loop

If you are advised to use a for...in loop, remember that iterating over arrays is not what it is intended for. Contrary to a common misconception, the for...in loop does not iterate over array indices, but rather through enumerable properties of an object.

However, in some cases, such as iterating over sparse arrays, for...in can be useful, as long as you take precautions, as shown in the example below:

// a - sparse array var a = ; a = "a"; a = "b"; a = "c"; for (var key in a) ( if (a.hasOwnProperty(key) && /^0$|^\d*$/.test(key) && key<= 4294967294) { console.log(a); } }
In this example, two checks are performed at each iteration of the loop:

  1. that the array has its own property called key (not inherited from its prototype).
  2. that key is a string containing the decimal representation of an integer whose value is less than 4294967294 . Where does the last number come from? From the definition of an array index in ES5, which shows that the highest index an element in an array can have is: (2^32 - 2) = 4294967294 .
Of course, such checks will take up unnecessary time when executing the loop. But in the case of a sparse array, this method is more efficient than a for loop, since in this case only those elements that are explicitly defined in the array are iterated. So, in the example above, only 3 iterations will be performed (for indexes 0, 10 and 10000) - versus 10001 in the for loop.

In order not to write such a cumbersome check code every time you need to iterate through an array, you can write it as a separate function:

Function arrayHasOwnIndex(array, key) ( return array.hasOwnProperty(key) && /^0$|^\d*$/.test(key) && key<= 4294967294; }
Then the body of the loop from the example will be significantly reduced:

For (key in a) ( if (arrayHasOwnIndex(a, key)) ( console.log(a); ) )
The check code discussed above is universal, suitable for all cases. But instead, you can use a shorter version, although formally not entirely correct, but nevertheless suitable for most cases:

For (key in a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === key) ( console.log(a); ) )

4. For...of loop (implicit use of iterator)

ES6, still in draft status, should introduce iterators to JavaScript.

Iterator is a protocol implemented by an object that defines a standard way to obtain a sequence of values ​​(finite or infinite).
An iterator is an object that defines a next() method - a no-argument function that returns an object with two properties:

  1. done (boolean) - true if the iterator has reached the end of the iterable sequence. Otherwise the value is false .
  2. value - defines the value returned by the iterator. May be undefined (missing) if the done property is true .
Many built-in objects, incl. real arrays have iterators by default. The simplest way to use an iterator on real arrays is to use the new for...of construct.

Example of using for...of:

Varval; var a = ["a", "b", "c"]; for (val of a) ( console.log(val); )
In the example above, the for...of loop implicitly calls the Array object's iterator to obtain each value of the array.

5. Explicit use of iterator

Iterators can also be used explicitly, however, in this case the code becomes much more complicated compared to the for...of loop. It looks something like this:

Var a = ["a", "b", "c"]; var it = a.entries(); var entry; while (!(entry = it.next()).done) ( console.log(entry.value); )
In this example, the Array.prototype.entries method returns an iterator that is used to display the values ​​of the array. At each iteration, entry.value contains an array of the form [key, value] .

II. Iterating over array-like objects

In addition to real arrays, in JavaScript there are also array-like objects . What they have in common with real arrays is that they have a length property and properties named as numbers corresponding to the elements of the array. Examples include the DOM of the NodeList collection and the arguments pseudo-array, available inside any function/method.

1. Using methods to iterate over real arrays

At a minimum, most, if not all, methods of iterating over real arrays can be used to iterate over array-like objects.

The for and for...in constructs can be applied to array-like objects in exactly the same way as they are applied to real arrays.

ForEach and other Array.prototype methods also apply to array-like objects. To do this you need to use Function.call or Function.apply .

For example, if you want to apply forEach to the childNodes property of a Node object, you would do it like this:

Array.prototype.forEach.call(node.childNodes, function(child) ( // do something with the child object));
To make this trick easier to reuse, you can declare a reference to the Array.prototype.forEach method in a separate variable and use it as a shortcut:

// (Assuming all code below is in the same scope) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // do something with the child object));
If an array-like object has an iterator, it can be used explicitly or implicitly to iterate over the object in the same way as for real arrays.

2. Convert to a real array

There is also another, very simple way to iterate over an array-like object: convert it into a real array and use any of the methods discussed above for iterating over real arrays. For conversion, you can use the generic Array.prototype.slice method, which can be applied to any array-like object. This is done very simply, as shown in the example below:

Var trueArray = Array.prototype.slice.call(arrayLikeObject, 0);
For example, if you wanted to convert a NodeList collection into an actual array, you'd need code something like this:

Var divs = Array.prototype.slice.call(document.querySelectorAll("div"), 0);
Update: As noted in the comments

22 answers

After running this test with most modern browsers...

Currently the fastest form of loop (and, in my opinion, the most syntactically obvious).

standard for length-cached loop

For (var i = 0, len = myArray.length; i< len; i++) { }

I'd say this is definitely a case where I applaud JavaScript engine developers. Execution time should be optimized for clarity, not for convenience.

As of June 2016, several tests in the latest Chrome (71% of the browser market in May 2016 and increasing):

  • The fastest cycle is the cycle of the cycle, both with and without cache length, providing very similar performance. (A for loop with a cached length sometimes produces better results than one that is not cached, but the difference is almost negligible, meaning that the engine may be optimized in favor of the standard and perhaps simplest loop without a cache).
  • The while loop with decrements was about 1.5 times slower than the for loop.
  • A loop using a callback function (eg standard forEach) was about 10 times slower than a for loop.

I believe this thread is too old, and programmers feel they need to cache the length, or use back-decrease intersections to achieve better performance, writing code that is less picky and more error-prone than just a simple for-loop. Therefore I recommend:

    If your application iterates through a lot of elements, or your loop code is inside a function that is used frequently, a straight loop is the answer:

    For (var i = 0; i< arr.length; i++) { // Do stuff with arr[i] or i }

    If your application doesn't really iterate over a lot of elements or you just need to do small iterations here and there, using the standard forEach callback or any similar function from your JS library of choice may be cleaner and less error prone since the index variable scope is private and you There is no need to use parentheses that directly access the array value:

    Arr.forEach(function(value, index) ( // Do stuff with value or index ));

    If you really need to mash a few milliseconds while iterating over billions of rows, and the length of the array won't change in the process, you might consider caching the length in a for loop. Although I think it's really not necessary these days:

    For (var i = 0, len = arr.length; i< len; i++) { // Do stuff with arr[i] }

It's just 2018, so an update might be good...

And I really should disagree with the accepted answer. It depends on different browsers. some do forEach faster, some for-loop and some while tests all methods http://jsben.ch/mW36e

Arr.forEach(a => ( // ... )

and since you can see a lot of for(a = 0;...) loops like for(a = 0;...) it's worth mentioning that without variables "var" will be defined globally and this can have a significant impact speed, so it will be slow.

var arr = arr = new Array(11111111).fill(255); var benches = [ [ "empty", () =>< l; a++); }] , ["for-loop", () =>( for(var a = 0, l = arr.length; a< l; ++a) var b = arr[a] + 1; }] , ["for-loop++", () =>( for(var a = 0, l = arr.length; a< l; a++) var b = arr[a] + 1; }] , ["for-loop - arr.length", () =>( for(var a = 0; a< arr.length; ++a) var b = arr[a] + 1; }] , ["reverse for-loop", () =>( for(var a = arr.length - 1; a >= 0; --a) var b = arr[a] + 1; )] ,["while-loop", () => ( var a = 0 , l = arr.length; while(a< l) { var b = arr[a] + 1; ++a; } }] , ["reverse-do-while-loop", () =>( var a = arr.length - 1; // CAREFUL do ( var b = arr[a] + 1; ) while(a--); )] , ["forEach", () => ( arr.forEach( a => ( var b = a + 1; )); )], ["for..in (only 3.3%)", () => ( var ar = arr.slice(0,arr.length/33) ; for(const a in ar) ( var b = a + 1; ) )] , ["Duff device", () => ( var i = 0; var r = arr.length % 8; var n = (arr .length - r) / 8; if (r > 0) do ( var b = arr + 1; ) while (--r); if (n > 0) do ( var b = arr[i] + 1; var c = arr + 1; var d = arr + 1; var e = arr + 1; var f = arr + 1; var g = arr + 1; var h = arr + 1; var k = arr + 1; i = --n >>> 3; ) while (n); )] , ["Duff device negative", () => ( var r = arr.length % 8; var n = (arr.length-r) / 8 ; ///Math.floor(arr.length / 8); var i = arr.length ; // -1; while(r)( var b = arr[--i] + 1; --r; ) while (n)( var b = arr[i] + 1; var c = arr + 1; var d = arr + 1; var e = arr + 1; var f = arr + 1; var g = arr + 1; var h = arr + 1; var j = arr + 1; i = --n >>> 3; ) )]]; function bench(title, f) ( var t0 = performance.now(); var res = f(); return performance.now() - t0; // console.log("$(title) took $(t1-t0 ) msec"); ) var globalVarTime = bench("for-loop without "var"", () => ( // Here if you forget to put "var" so variables"ll be global for(a = 0, l =arr.length;a< l; ++a) var b = arr[a] + 1; }); var times = benches.map(function(a) { arr = new Array(11111111).fill(255); return }).sort((a,b) =>a-b); var max = times; times = times.map(a => (a = (a/max)*100; return a; )); var template = (title, time, n) => "

" + "$(title) " + " $(Number(time.toFixed(3)))msec" + "
"; var strRes = times.map(t => template(...t)).join("\n") + "

for-loop without "var" $(globalVarTime) msec."; var $container = document.getElementById("container"); $container.innerHTML = strRes; body ( color:#fff; background:#333; font-family :helvetica; ) body > div > div ( clear:both ) body > div > div > span ( float:left; width:43%; margin:3px 0; text-align:right; ) body > div > div > span :nth-child(2) ( text-align:left; background:darkorange; animation:showup .37s .111s; -webkit-animation:showup .37s .111s; ) @keyframes showup ( from ( width:0; ) ) @-webkit-keyframes showup ( from ( width:0; ) )

2014 While ago

Think logically.

Look at this

For(var index = 0 , length = array.length ; index< length ; index++) { //do stuff }

  • You need to create at least 2 variables (index, length)
  • Need to check if the length indicator is less than
  • Index needs to be increased
  • the for loop has 3 parameters

Now tell me why this should be faster than:

Var length = array.length; while(--length) ( //or length-- //do stuff )

  • One variable
  • No checks
  • index decreases (machines prefer this)
  • While has only one parameter

I was completely confused when Chrome 28 showed that the for loop was faster than time. It should be something like

"Well, everyone uses a for loop, let's focus on that when for chrome."

But now in 2014, the while loop is coming back to chrome. it's 2x faster, in other/old browsers it was always faster.

I've done some new tests lately. Now in the real envoirement world these shortcodes are worthless and jsperf can't actually execute the while loop correctly because it needs to recreate array.length which also takes time.

CANNOT get the actual speed of the while loop on jsperf.

you need to create your own function and check that using window.performance.now()

And yes... there is no way for a while loop to be faster.

The real issue is the actual manipulation/playback time/drawing time or whatever you want to call it.

For example, I have a canvas scene where I need to calculate coordinates and collisions... this is done between 10-200 MicroSeconds (not milliseconds). it actually takes various milliseconds to do everything. Same as in DOM.

There is another super efficient way to use loop in some cases... for example to copy/clone an array

For(var i = array.length; i > 0; arrayCopy[ --i ] = array[ i ] // doing stuff);

Please note the parameter settings:

  • Same as in the while loop. I only use one variable
  • You need to check if the index is greater than 0;
  • As you can see, this approach is different from the usual loop that everyone uses, since I'm doing stuff inside the 3rd parameter, and also decrementing directly inside the array.

It is said that this confirms that machines such as

wrote that I thought to make it a little shorter and remove some useless stuff and wrote this one using the same style:

For(var i = array.length ; i-- ; arrayCopy[ i ] = array[ i ] // doing stuff);

Even if it's shorter, it seems like using i once again slows everything down. This is 1/5 slower than the previous for and while loop.

Note:; very important after for looo without ()

Even if I just told you that jsperf is not the best way to test scripts. I have added 2 loops here.

And here is another answer about performance in javascript

This answer should show performant ways of writing javascript. So if you can't read this, ask and you will get an answer or read a book about javascript http://www.ecma-international.org/ecma-262/5.1/

The latest revision of the test I prepared (by reusing an older one) shows one thing.

The cache length isn't that important, but it doesn't hurt.

Every first run of the test linked above (in the newly opened tab) gives the best results for the last 4 fragments (3rd, 5th, 7th and 10th in the charts) in Chrome, Opera and Firefox on my 64- bit Debian Squeeze (my desktop hardware). Subsequent runs give a completely different result.

The performance conclusions are simple:

  • Go into a for loop (forward) and check with !== instead< .
  • If you don't need to reuse the array later, then a loop with reduced length and destructive array shift() -ing is also effective.

Currently (2011.10) the template below appears to be the fastest.

For (var i = 0, len = arr.length; i !== len; i++) ( ... )

Remember that caching arr.length is not critical here, so you can just test i !== arr.length and there will be no performance hit, but you will get shorter code.

PS: I know that in a fragment with shift() its result can be used instead of accessing the 0th element, but I somehow overlooked that after reusing the previous revision (which had the wrong value during loops), and Later I did not want to lose the results already obtained.

“Best” as in pure performance? or performance AND?

The pure "best" performance is that which uses the cache and the ++ prefix operator (my data: http://jsperf.com/caching-array-length/189)

For (var i = 0, len = myArray.length; i< len; ++i) { // blah blah }

I'd say a cache-less loop is the best balance of execution time and programmer read time. Every programmer starting with C/C++/Java will not spend ms to read this

For(var i=0; i< arr.length; i++){ // blah blah }

** cache the length of the array inside the loop, some seconds of time will slip away. Depends on the elements in the array, if there are more elements in the array there is a big difference regarding Ms time*

SArr; //Array; for(var i = 0 ; i

SArr; //Array; for(var i = 0,len = sArr.length ; i< len ; i++) { callArray(sArr[i]); //function call } ***end: 1.354ms***

This is the year 2017 .

I did some tests.

It looks like the while method is the fastest in Chrome.

It looks like the left decrement (--i) is much faster than the others (++i , i-- , i++) in Firefox.

This approach is fasting on average. But it iterates the array in reverse order.

Let i = array.length; while (--i >= 0) ( doSomething(array[i]); )

If priority order is important, use this approach.

Let ii = array.length; let i = 0; while(i< ii) { doSomething(array[i]); ++i; }

I always write in the first style.

Even if the compiler is smart enough to optimize it for arrays, but is it still smart if we use DOMNodeList here or some complex object with calculated length?

I know the question is about arrays, but I think it's good practice to write all your loops in the same style.

Var arr = ; // The array var i = 0; while(i< arr.length) { // Do something with arr[i] i++; }

i++ is faster than ++i, --i and i -

  • I. Iterating over real arrays
    1. forEach method and related methods
    2. for loop
    3. Proper use of the for...in loop
    4. for...of loop (implicit use of iterator)
    5. Explicit use of iterator
  • II. Iterating over array-like objects
    1. Using methods to iterate over real arrays
    2. Convert to a real array
    3. A note on runtime objects

I. Iterating over real arrays

At the moment, there are three ways to iterate over the elements of a real array:

  1. method Array.prototype.forEach ;
  2. classic for loop
  3. a “correctly” constructed for...in loop.

In addition, soon, with the advent of the new ECMAScript 6 (ES 6) standard, two more methods are expected:

  1. for...of loop (implicit use of iterator);
  2. explicit use of iterator.

1. The forEach method and related methods

If your project is designed to support the features of the ECMAScript 5 (ES5) standard, you can use one of its innovations - the forEach method.

Usage example:

Var a = ["a", "b", "c"]; a.forEach(function(entry) ( console.log(entry); ));

In general, using forEach requires connecting the es5-shim emulation library for browsers that do not natively support this method. These include IE 8 and earlier, which are still in use in some places.

The advantage of forEach is that there is no need to declare local variables to store the index and value of the current array element, since they are automatically passed to the callback function as arguments.

If you're worried about the possible cost of calling a callback on each element, don't worry and read this.

forEach is designed to iterate through all the elements of an array, but besides it, ES5 offers several more useful methods for iterating through all or some elements plus performing some actions on them:

  • every - returns true if for each element of the array the callback returns a value that can be converted to true .
  • some - returns true if for at least one element of the array the callback returns a value that can be converted to true.
  • filter - creates a new array that includes those elements of the original array for which the callback returns true .
  • map - creates a new array consisting of the values ​​returned by the callback.
  • reduce - reduces an array to a single value, applying a callback to each element of the array in turn, starting with the first (can be useful for calculating the sum of array elements and other summary functions).
  • reduceRight - works similar to reduce, but iterates through elements in reverse order.

2. For loop

Good old for rules:

Var a = ["a", "b", "c"]; var index; for (index = 0; index< a.length; ++index) { console.log(a); }

If the length of the array is constant throughout the loop, and the loop itself belongs to a performance-critical section of code (which is unlikely), then you can use a “more optimal” version of for that stores the length of the array:

Var a = ["a", "b", "c"]; var index, len; for (index = 0, len = a.length; index< len; ++index) { console.log(a); }

In theory, this code should run a little faster than the previous one.

If the order of the elements is not important, then you can go even further in terms of optimization and get rid of the variable for storing the length of the array, changing the order of the search to the reverse:

Var a = ["a", "b", "c"]; var index; for (index = a.length - 1; index >= 0; --index) ( console.log(a); )

However, in modern JavaScript engines such optimization games usually mean nothing.

3. Correct use of the for...in loop

If you are advised to use a for...in loop, remember that iterating over arrays is not what it is intended for. Contrary to a common misconception, the for...in loop does not iterate over array indices, but rather through enumerable properties of an object.

However, in some cases, such as iterating over sparse arrays, for...in can be useful, as long as you take precautions, as shown in the example below:

// a - sparse array var a = ; a = "a"; a = "b"; a = "c"; for (var key in a) ( if (a.hasOwnProperty(key) && /^0$|^d*$/.test(key) && key<= 4294967294) { console.log(a); } }

In this example, two checks are performed at each iteration of the loop:

  1. that the array has its own property called key (not inherited from its prototype).
  2. that key is a string containing the decimal representation of an integer whose value is less than 4294967294 . Where does the last number come from? From the definition of an array index in ES5, which shows that the highest index an element in an array can have is: (2^32 - 2) = 4294967294 .

Of course, such checks will take up unnecessary time when executing the loop. But in the case of a sparse array, this method is more efficient than a for loop, since in this case only those elements that are explicitly defined in the array are iterated. So, in the example above, only 3 iterations will be performed (for indexes 0, 10 and 10000) - versus 10001 in the for loop.

In order not to write such a cumbersome check code every time you need to iterate through an array, you can write it as a separate function:

Function arrayHasOwnIndex(array, key) ( return array.hasOwnProperty(key) && /^0$|^d*$/.test(key) && key<= 4294967294; }

Then the body of the loop from the example will be significantly reduced:

For (key in a) ( if (arrayHasOwnIndex(a, key)) ( console.log(a); ) )

The check code discussed above is universal, suitable for all cases. But instead, you can use a shorter version, although formally not entirely correct, but nevertheless suitable for most cases:

For (key in a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === key) ( console.log(a); ) )

4. For...of loop (implicit use of iterator)

ES6, still in draft status, should introduce iterators to JavaScript.

Iterator is a protocol implemented by an object that defines a standard way to obtain a sequence of values ​​(finite or infinite).
An object has an iterator if it defines a next() method, a no-argument function that returns an object with two properties:

  1. done (boolean) - true if the iterator has reached the end of the iterable sequence. Otherwise the value is false .
  2. value - defines the value returned by the iterator. May be undefined (missing) if the done property is true .

Many built-in objects, incl. real arrays have iterators by default. The simplest way to use an iterator on real arrays is to use the new for...of construct.

Example of using for...of:

Varval; var a = ["a", "b", "c"]; for (val of a) ( console.log(val); )

In the example above, the for...of loop implicitly calls the Array object's iterator to obtain each value of the array.

5. Explicit use of iterator

Iterators can also be used explicitly, however, in this case the code becomes much more complicated compared to the for...of loop. It looks something like this:

Var a = ["a", "b", "c"]; var entry; while (!(entry = a.next()).done) ( console.log(entry.value); )

II. Iterating over array-like objects

In addition to real arrays, in JavaScript there are also array-like objects . What they have in common with real arrays is that they have a length property and properties named as numbers corresponding to the elements of the array. Examples include the DOM of the NodeList collection and the arguments pseudo-array, available inside any function/method.

1. Using methods to iterate over real arrays

At a minimum, most, if not all, methods of iterating over real arrays can be used to iterate over array-like objects.

The for and for...in constructs can be applied to array-like objects in exactly the same way as they are applied to real arrays.

forEach and other Array.prototype methods also apply to array-like objects. To do this you need to use Function.call or Function.apply .

For example, if you want to apply forEach to the childNodes property of a Node object, you would do it like this:

Array.prototype.forEach.call(node.childNodes, function(child) ( // do something with the child object));

To make this trick easier to reuse, you can declare a reference to the Array.prototype.forEach method in a separate variable and use it as a shortcut:

// (Assuming all code below is in the same scope) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // do something with the child object));

If an array-like object has an iterator, it can be used explicitly or implicitly to iterate over the object in the same way as for real arrays.

2. Convert to a real array

There is also another, very simple way to iterate over an array-like object: convert it into a real array and use any of the methods discussed above for iterating over real arrays. For conversion, you can use the generic Array.prototype.slice method, which can be applied to any array-like object. This is done very simply, as shown in the example below:

Var trueArray = Array.prototype.slice.call(arrayLikeObject, 0);

For example, if you wanted to convert a NodeList collection into an actual array, you'd need code something like this:

Var divs = Array.prototype.slice.call(document.querySelectorAll("div"), 0);

3. A note on runtime objects

If you apply Array.prototype methods to runtime objects (such as DOM collections), then you should be aware that these methods are not guaranteed to work correctly in all runtime environments (including browsers). This depends on the behavior of a particular object in a particular execution environment, or more precisely, on how the abstract operation HasProperty is implemented in this object. The problem is that the ES5 standard itself allows for the possibility of an object misbehaving with respect to this operation (see §8.6.2).

Therefore, it is important to test the operation of the Array.prototype methods in each runtime environment (browser) in which you plan to use your application.







2024 gtavrl.ru.