The for...in
statement iterates over the enumerable properties of an object, in original insertion order. For each distinct property, statements can be executed.
Syntax
for (variable in object) { ... }
variable
- A different property name is assigned to variable on each iteration.
object
- Object whose enumerable properties are iterated.
Description
A for...in
loop only iterates over enumerable properties. Objects created from built–in constructors like Array
and Object
have inherited non–enumerable properties from Object.prototype
and String.prototype
, such as String
's indexOf()
method or Object
's toString()
method. The loop will iterate over all enumerable properties of the object itself and those the object inherits from its constructor's prototype (properties closer to the object in the prototype chain override prototypes' properties).
Deleted, added or modified properties
A for...in
loop iterates over the properties of an object in an arbitrary order (see the delete
operator for more on why one cannot depend on the seeming orderliness of iteration, at least in a cross-browser setting). If a property is modified in one iteration and then visited at a later time, its value in the loop is its value at that later time. A property that is deleted before it has been visited will not be visited later. Properties added to the object over which iteration is occurring may either be visited or omitted from iteration. In general it is best not to add, modify or remove properties from the object during iteration, other than the property currently being visited. There is no guarantee whether or not an added property will be visited, whether a modified property (other than the current one) will be visited before or after it is modified, or whether a deleted property will be visited before it is deleted.
Array iteration and for...in
Note: for...in
should not be used to iterate over an Array
where the index order is important.
Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in
will return the indexes in any particular order. The for...in
loop statement will return all enumerable properties, including those with non–integer names and those that are inherited.
Because the order of iteration is implementation-dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for
loop with a numeric index (or Array.prototype.forEach()
or the for...of
loop) when iterating over arrays where the order of access is important.
Iterating over own properties only
If you only want to consider properties attached to the object itself, and not its prototypes, use getOwnPropertyNames()
or perform a hasOwnProperty()
check (propertyIsEnumerable
can also be used). Alternatively, if you know there won't be any outside code interference, you can extend built-in prototypes with a check method.
Examples
The following function takes as its argument an object. It then iterates over all the object's enumerable properties and returns a string of the property names and their values.
var obj = {a: 1, b: 2, c: 3}; for (var prop in obj) { console.log(`obj.${prop} = ${obj[prop]}`); } // Output: // "obj.a = 1" // "obj.b = 2" // "obj.c = 3"
The following function illustrates the use of hasOwnProperty()
: the inherited properties are not displayed.
var triangle = {a: 1, b: 2, c: 3}; function ColoredTriangle() { this.color = 'red'; } ColoredTriangle.prototype = triangle; var obj = new ColoredTriangle(); for (var prop in obj) { if (obj.hasOwnProperty(prop)) { console.log(`obj.${prop} = ${obj[prop]}`); } } // Output: // "obj.color = red"
Specifications
Browser compatibility
Feature | Chrome | Edge | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | 6 | (Yes) | (Yes) |
Feature | Android | Chrome for Android | Edge | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|---|
Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |
Compatibility: Initializer expressions in strict mode
Prior to SpiderMonkey 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37), it was possible to use an initializer expression (i=0
) in a for...in
loop:
var obj = {a: 1, b: 2, c: 3}; for (var i = 0 in obj) { console.log(obj[i]); } // 1 // 2 // 3
This non-standard behavior is now ignored in version 40 and later and will present a SyntaxError
("for-in loop head declarations may not have initializers") error in strict mode (bug 748550 and bug 1164741).
Other engines like v8 (Chrome), Chakra (IE/Edge), and JSC (WebKit/Safari) are investigating to remove the non-standard behavior as well.
See also
for...of
- a similar statement that iterates over the property valuesfor each in
- a similar statement, but iterates over the values of object's properties, rather than the property names themselves (deprecated)for
- Generator expressions (uses the
for...in
syntax) - Enumerability and ownership of properties
Object.getOwnPropertyNames()
Object.prototype.hasOwnProperty()
Array.prototype.forEach()