Iterating over properties in objects. All Ways to Iterate through an Array in JavaScript A Note on Runtime Objects

The forEach() method executes a provided function once for each array element.

The source for this interactive example is stored in a GitHub repository. If you"d like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

Syntax

arr .forEach(callback(currentValue [, index [, array]]) [, thisArg ]);

Parameters

callback Function to execute on each element, taking three arguments: currentValue The current element being processed in the array. index Optional The index of the current element being processed in the array. array Optional The array forEach() was called upon. thisArg Optional Value to use as this when executing callback .

Return value

Description

forEach() calls a provided callback function once for each element in an array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (i.e. on sparse arrays, ).

callback is invoked with three arguments:

  1. the value of the element
  2. the index of the element
  3. the Array object being traversed

If a thisArg parameter is provided to forEach() , it will be used as callback"s this value. The this value is ultimately observable by callback is determined according to the usual rules for determining the this seen by a function .

The range of elements processed by forEach() is set before the first invocation of callback . Elements which are appended to the array after the call to forEach() begins will not be visited by callback . If existing elements of the array are changed or deleted, their value as passed to callback will be the value at the time forEach() visits them; elements that are deleted before being visited are not visited. If elements that are already visited are removed (e.g. using shift()) during the iteration, later elements will be skipped - see example below .

forEach() executes the callback function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable. The typical use case is to execute side effects at the end of a chain.

forEach() does not mutate the array on which it is called (although callback , if invoked, may do so).

There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.

Early termination may be accomplished with:

Array methods: every() , some() , find() , and findIndex() test the array elements with a predicate returning a truthy value to determine if further iteration is required.

Examples

No operation for uninitialized values ​​(sparse arrays)

const arraySparse = ; let numCallbackRuns = 0; arraySparse.forEach(function(element)( console.log(element); numCallbackRuns++; )); console.log("numCallbackRuns: ", numCallbackRuns); // 1 // 3 // 7 // numCallbackRuns: 3 // comment: as you can see the missing value between 3 and 7 didn't invoke callback function.

Converting a for loop to forEach

const items = ["item1", "item2", "item3"]; const copy = ; // before for (let i=0; i Printing the contents of an array

Note: In order to display the content of an array in the console, you can use console.table() which will print a formatted version of the array. The following example illustrates another way of doing so, using forEach() .

The following code logs a line for each element in an array:

Function logArrayElements(element, index, array) ( console.log("a[" + index + "] = " + element); ) // Notice that index 2 is skipped since there is no item at // that position in the array. .forEach(logArrayElements); // logs: // a = 2 // a = 5 // a = 9

Using thisArg

The following (contrived) example updates an object"s properties from each entry in the array:

Function Counter() ( this.sum = 0; this.count = 0; ) Counter.prototype.add = function(array) ( array.forEach(function(entry) ( this.sum += entry; ++this.count ; ), this); // ^---- Note ); const obj = new Counter(); obj.add(); obj.count; // 3 obj.sum; // 16

Since the thisArg parameter (this) is provided to forEach() , it is passed to callback each time it"s invoked, for use as its this value.

An object copy function

The following code creates a copy of a given object. There are different ways to create a copy of an object; the following is just one way and is presented to explain how Array.prototype.forEach() works by using ECMAScript 5 Object.* meta property functions.

Function copy(obj) ( const copy = Object.create(Object.getPrototypeOf(obj)); const propNames = Object.getOwnPropertyNames(obj); propNames.forEach(function(name) ( const desc = Object.getOwnPropertyDescriptor(obj, name ); Object.defineProperty(copy, name, desc); )); return copy; ) const obj1 = ( a: 1, b: 2 ); const obj2 = copy(obj1); // obj2 looks like obj1 now

If the array is modified during iteration, other elements might be skipped.

The following example logs "one", "two", "four". When the entry containing the value "two" is reached, the first entry of the whole array is shifted off, which results in all remaining entries moving up one position. Because element "four" is now at an earlier position in the array, "three" will be skipped. forEach() does not make a copy of the array before iterating.!}

Var words = ["one", "two", "three", "four"]; words.forEach(function(word) ( console.log(word); if (word === "two") ( words.shift(); ) )); // one // two // four

Flatten an array

The following example is only here for learning purpose. If you want to flatten an array using built-in methods you can use Array.prototype.flat() (expected to be part of ES2019 and already implemented in some browsers).

/** * Flattens passed array in one dimensional array * * @params (array) arr * @returns (array) */ function flatten(arr) ( const result = arr.forEach((i) => ( if (Array. isArray(i)) ( result.push(...flatten(i)) ) else ( result.push(i) )) return result ) // Usage const problem = , 8, 9]] flatten(problem) / /

Specifications

Specification Status Comment
ECMAScript Latest Draft (ECMA-262)
Draft
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of "Array.prototype.forEach" in that specification.
Standard
ECMAScript 5.1 (ECMA-262)
The definition of "Array.prototype.forEach" in that specification.
Standard Initial definition. Implemented in JavaScript 1.6.

Browser compatibility

The compatibility table in this page is generated from structured data. If you"d like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
forEachChrome Full support YesEdge Full support 12Firefox Full support 1.5IE Full support 9Opera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes

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! In the last lesson, we looked at what objects are and why they are needed, and today we will look at how to work with the properties of an object and how to actually sort through all these properties. For these purposes, a for..in property loop is used (you can read about loops in JavaScript).

Loop for..in

Syntax:

For (key in obj) ( /* ... actions with obj ... */ )

The for..in loop will sequentially iterate through the properties of the obj object, writing the name of each property into key.

Declaring a variable in a for loop (var key in obj)

In this loop you can declare the key variable:

For (var key in menu1) ( // ... )

Let's look at an example of iterating through the properties of an object using a for...in loop:

Var menu = (width: 400, height: 300, title: "Menu My" ); for (var key in menu) ( // this code will work for each property of the object // ..and will display the property name and its value accordingly alert("Key: " + key + " value: " + menu); )

I would like to draw your attention to the fact that in the example we used square brackets menu. This is because if we store the name of a property in a variable, then we can only access it through square brackets, but not through a dot.

Loop for…of

There is also a new loop for traversing objects and arrays. Its syntax is very similar to the for...in loop, but the differences are that it does not output the keys or indexes of the array, but its values. Here's an example:

Var menu = (width: 400, height: 300, title: "Menu My" ); for (var key of menu) ( // this code will work for each property of the object // ..and display the property value accordingly alert("value: " + key +","); //400, 300, "Menu My" )

Number of properties in an object

But what if you need to know the number of properties in an object? How can I do that?

Unfortunately, there are no ready-made solutions for this issue.

The easiest way is to loop through the properties and calculate as follows:

Var menu = (width: 400, height: 300, title: "Menu My" ); var count = 0; for (var key in menu) ( count++; ) alert("Total properties: " + count);

Results

  • To iterate through the properties of an object, a key loop is used: for (key in obj).

Tasks

Determine if an object is empty

Create a function isEmptyObject(obj) that returns true if the object has no properties and false if there is at least one property.

It should work like this:

Function isEmptyObject(obj) ( /* your code */ ) var obj = (); alert(isEmptyObject(obj)); // true obj["8:30"] = "rise"; alert(isEmptyObject(obj)); // false

Calculate the arithmetic mean of all object properties

There is a salary object with salaries. Write a code that will display the arithmetic average of all salaries.
If the object is empty, then the result should be 0.
For example.

It works like this:

// REQUIRES ECMASCRIPT 2015+ var s, myStringArray = ["Hello", "World"]; for (s of myStringArray) ( // ... do something with s ... )

Or better yet, since ECMAScript 2015 also provides block-scoped variables with let and const:

// REQUIRES ECMASCRIPT 2015+ const myStringArray = ["Hello", "World"]; for (const s of myStringArray) ( // ... do something with s ... ) // s is no longer defined here

A note about sparse arrays: an array in JavaScript may not actually store as many elements as specified in its length ; this reported number is simply one greater than the highest index at which the value is stored. If an array contains fewer elements than its length indicates, it is said to be sparse. For example, it is perfectly legal to have an array with elements only at indexes 3, 12, and 247; The length of such an array is specified as 248, although in fact it only stores 3 values. If you try to access the element at any other index, the array will have an undefined value. So when you want to "iterate" an array, you have a question that needs to be answered: do you want to iterate over the entire range specified by its length and process undefined for any missing elements, or do you want to process only the elements actually present? There are many applications for both approaches; it just depends on what you are using the array for.

If you iterate over an array with for .. of , the body of the loop is executed by length and the loop control variable is set to undefined for any elements that are not actually in the array. Depending on the details of your "do something" code, this behavior may be what you want, but if it's not what you want, you should use a different approach.

Of course, some developers have no choice but to use a different approach anyway, because for some reason they are targeting a version of JavaScript that is not yet supported for ... of .

As long as your JavaScript implementation is compatible with a previous version of the ECMAScript specification (which, for example, excludes versions of Internet Explorer before 9), you can use the Array#forEach iterator method instead of a loop. In this case, you pass a function that will be called for each element in the array:

Var myStringArray = [ "Hello", "World" ]; myStringArray.forEach(function(s) ( // ... do something with s ... ));

Unlike for ... of , .forEach only calls the function on elements that actually contain values. If we pass our hypothetical array with three elements and a length of 248, it will only call the function three times, not 248 times. It also distinguishes between missing elements and elements that are actually set to undefined ; for the latter, it will still call the function, passing an undefined value as an argument. If this is how you want to handle sparse arrays, .forEach might be the way to go, even if your translator supports for ... of .

The final option, which works in all versions of JavaScript, is an explicit count loop. You simply count from 0 to one less than the length and use the counter as an index. The main loop looks like this:

One advantage of this approach is that you can choose how to handle sparse arrays; The above code will run the loop body over the full length with s set to undefined for any missing elements, like for .. of . If instead you want to only process actually existing elements of a sparse array, such as .forEach , you can add a simple check to the index:

Var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length; for (i=0; i

Assigning the length value to a local variable (as opposed to including the full myStringArray.length expression in the loop condition) can have a significant performance impact because it skips the property lookup all the way to the end each time; When using Rhino on my machine the speedup is 43%.

You can see that the length caching is done in the loop initialization clause, like this:

Var i, len, myStringArray = [ "Hello", "World" ]; for (len = myStringArray.length, i=0; i

The for ... in syntax mentioned by others is used to loop through the properties of an object; since an array in JavaScript is just an object with numeric property names (and an automatically updated length property), you could theoretically loop the array with it. But the problem is that it is not limited to numeric property values ​​(remember that even methods are really just properties whose value is a closure), nor is it guaranteed to be repeated in numeric order. Therefore, the for ... in syntax should not be used to loop through arrays.

  • 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.