admin管理员组文章数量:1125457
I know what is a for... in
loop (it iterates over the keys), but I have heard about for... of
for the first time (it iterates over values).
I am confused about for... of
loop.
var arr = [3, 5, 7];
arr.foo = "hello";
for (var i in arr) {
console.log(i); // logs "0", "1", "2", "foo"
}
for (var i of arr) {
console.log(i); // logs "3", "5", "7"
// it doesn't log "3", "5", "7", "hello"
}
I understand that for... of
iterates over property values. Then why doesn't it log "3", "5", "7", "hello"
instead of "3", "5", "7"
?
Unlike for... in
loop, which iterates over each key ("0", "1", "2", "foo"
) and also iterates over the foo
key, the for... of
does not iterate over the value of foo
property, i.e., "hello"
. Why it is like that?
Here I console for... of
loop. It should log "3", "5", "7","hello"
but it logs "3", "5", "7"
. Why?
Example Link
I know what is a for... in
loop (it iterates over the keys), but I have heard about for... of
for the first time (it iterates over values).
I am confused about for... of
loop.
var arr = [3, 5, 7];
arr.foo = "hello";
for (var i in arr) {
console.log(i); // logs "0", "1", "2", "foo"
}
for (var i of arr) {
console.log(i); // logs "3", "5", "7"
// it doesn't log "3", "5", "7", "hello"
}
I understand that for... of
iterates over property values. Then why doesn't it log "3", "5", "7", "hello"
instead of "3", "5", "7"
?
Unlike for... in
loop, which iterates over each key ("0", "1", "2", "foo"
) and also iterates over the foo
key, the for... of
does not iterate over the value of foo
property, i.e., "hello"
. Why it is like that?
Here I console for... of
loop. It should log "3", "5", "7","hello"
but it logs "3", "5", "7"
. Why?
Example Link
Share Improve this question edited May 21, 2023 at 5:30 Top-Master 8,6855 gold badges47 silver badges85 bronze badges asked Mar 26, 2015 at 18:14 Mukund KumarMukund Kumar 23.1k20 gold badges63 silver badges84 bronze badges 5 |21 Answers
Reset to default 846for in
loops over enumerable property names of an object.
for of
(new in ES6) does use an object-specific iterator and loops over the values generated by that.
In your example, the array iterator does yield all the values in the array (ignoring non-index properties).
I found a complete answer at Iterators and Generators (Although it is for TypeScript, this is the same for JavaScript too)
Both
for..of
andfor..in
statements iterate over lists; the values iterated on are different though,for..in
returns a list of keys on the object being iterated, whereasfor..of
returns a list of values of the numeric properties of the object being iterated.Here is an example that demonstrates this distinction:
let list = [4, 5, 6]; for (let i in list) { console.log(i); // "0", "1", "2", } for (let i of list) { console.log(i); // 4, 5, 6 }
Another distinction is that
for..in
operates on any object; it serves as a way to inspect properties on this object.for..of
on the other hand, is mainly interested in values of iterable objects. Built-in objects likeMap
andSet
implementSymbol.iterator
property allowing access to stored values.let pets = new Set(["Cat", "Dog", "Hamster"]); pets["species"] = "mammals"; for (let pet in pets) { console.log(pet); // "species" } for (let pet of pets) { console.log(pet); // "Cat", "Dog", "Hamster" }
Difference for..in
and for..of
:
Both for..in
and for..of
are looping constructs which are used to iterate over data structures. The only difference between them is the entities
they iterate over:
for..in
iterates over all enumerable property keys of an objectfor..of
iterates over the values of an iterable object. Examples of iterable objects are arrays, strings, and NodeLists.
Example:
let arr = ['el1', 'el2', 'el3'];
arr.addedProp = 'arrProp';
// elKey are the property keys
for (let elKey in arr) {
console.log(elKey);
}
// elValue are the property values
for (let elValue of arr) {
console.log(elValue)
}
In this example we can observe that the for..in
loop iterates over the keys of the object, which is an array object in this example. The keys are 0, 1, 2 (which correspond to the array elements) and addedProp
. This is how the arr
array object looks in chrome devtools:
You see that our for..in
loop does nothing more than simply iterating over these keys.
The for..of
loop in our example iterates over the values of a data structure. The values in this specific example are 'el1', 'el2', 'el3'
. The values which an iterable data structure will return using for..of
is dependent on the type of iterable object. For example an array will return the values of all the array elements whereas a string returns every individual character of the string.
For...in loop
The for...in loop improves upon the weaknesses of the for loop by eliminating the counting logic and exit condition.
Example:
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
console.log(digits[index]);
}
But, you still have to deal with the issue of using an index to access the values of the array, and that stinks; it almost makes it more confusing than before.
Also, the for...in loop can get you into big trouble when you need to add an extra method to an array (or another object). Because for...in loops loop over all enumerable properties, this means if you add any additional properties to the array's prototype, then those properties will also appear in the loop.
Array.prototype.decimalfy = function() {
for (let i = 0; i < this.length; i++) {
this[i] = this[i].toFixed(2);
}
};
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
console.log(digits[index]);
}
Prints:
0
1
2
3
4
5
6
7
8
9
function() { for (let i = 0; i < this.length; i++) { this[i] = this[i].toFixed(2); } }
This is why for...in loops are discouraged when looping over arrays.
NOTE: The forEach loop is another type of for loop in JavaScript. However,
forEach()
is actually an array method, so it can only be used exclusively with arrays. There is also no way to stop or break a forEach loop. If you need that type of behavior in your loop, you’ll have to use a basic for loop.
For...of loop
The for...of loop is used to loop over any type of data that is iterable.
Example:
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
console.log(digit);
}
Prints:
0
1
2
3
4
5
6
7
8
9
This makes the for...of loop the most concise version of all the for loops.
But wait, there’s more! The for...of loop also has some additional benefits that fix the weaknesses of the for and for...in loops.
You can stop or break a for...of loop at anytime.
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
if (digit % 2 === 0) {
continue;
}
console.log(digit);
}
Prints:
1
3
5
7
9
And you don’t have to worry about adding new properties to objects. The for...of loop will only loop over the values in the object.
Here is a useful mnemonic for remembering the difference between for...in
Loop and for...of
Loop.
"index in, object of"
for...in Loop
=> iterates over the index in the array.
for...of Loop
=> iterates over the object of objects.
for of
is used to iterate over iterables and for in
is used to iterate over object properties
Here's a trick to remember:
for of
is not for objects (so it's for iterables)
for in
is not for iterables (so it's for objects)
Another trick:
for in
returns object indices (keys) while for of
returns values
//for in, iterates keys in an object and indexes in an array
let obj={a:1, b:2}
for( const key in obj)
console.log(obj[key]); //would print 1 and 2
console.log(key); //would print a and b
let arr = [10, 11, 12, 13];
for (const item in arr)
console.log(item); //would print 0 1 2 3
//for of, iterates values in an array or any iterable
let arr = [10, 11, 12, 13];
for (const item of arr )
console.log(item); //would print 10 11 12 13
Short answer: for...in
loops over keys, while for...of
loops over values.
for (let x in ['a', 'b', 'c', 'd'] {
console.log(x);
}
// Output
0
1
2
3
for (let x of ['a', 'b', 'c', 'd'] {
console.log(x);
}
// Output
a
b
c
d
Another difference between the two loops, which nobody has mentioned before:
Destructuring
for...in
is deprecated. Usefor...of
instead.
Source
So if we want to use destructuring in a loop, for get both index and value of each array element, we should to use the for...of
loop with the Array method entries()
:
for (const [idx, el] of arr.entries()) {
console.log( idx + ': ' + el );
}
Just remember that for in
is used for objects, while for of
is used for arrays, strings, etc.
However, you don't even need to use for in
. You can always use for of
instead:
const person = {name: 'John', age: 31};
for (let key in person) {
console.log(key, ': ', person[key]); // name: John
} // age: 31
for (let [key, value] of Object.entries(person)) {
console.log(key, ': ', value); // The same output
}
The for...in
statement iterates over the enumerable properties of an object, in an arbitrary order.
Enumerable properties are those properties whose internal [[Enumerable]] flag is set to true, hence if there is any enumerable property in the prototype chain, the for...in
loop will iterate on those as well.
The for...of
statement iterates over data that iterable object defines to be iterated over.
Example:
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
for (let i in iterable) {
console.log(i); // logs: 0, 1, 2, "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs: 0, 1, 2,
}
}
for (let i of iterable) {
console.log(i); // logs: 3, 5, 7
}
Like earlier, you can skip adding hasOwnProperty
in for...of
loops.
The for-in statement iterates over the enumerable properties of an object, in arbitrary order.
The loop will iterate over all enumerable properties of the object itself and those the object inherits from its constructor's prototype
You can think of it as "for in" basically iterates and list out all the keys.
var str = 'abc';
var arrForOf = [];
var arrForIn = [];
for(value of str){
arrForOf.push(value);
}
for(value in str){
arrForIn.push(value);
}
console.log(arrForOf);
// ["a", "b", "c"]
console.log(arrForIn);
// ["0", "1", "2", "formatUnicorn", "truncate", "splitOnLast", "contains"]
There are some already defined data types which allows us to iterate over them easily e.g Array, Map, String Objects
Normal for in iterates over the iterator and in response provides us with the keys that are in the order of insertion as shown in below example.
const numbers = [1,2,3,4,5];
for(let number in number) {
console.log(number);
}
// result: 0, 1, 2, 3, 4
Now if we try same with for of, then in response it provides us with the values not the keys. e.g
const numbers = [1,2,3,4,5];
for(let numbers of numbers) {
console.log(number);
}
// result: 1, 2, 3, 4, 5
So looking at both of the iterators we can easily differentiate the difference between both of them.
Note:- For of only works with the Symbol.iterator
So if we try to iterate over normal object, then it will give us an error e.g-
const Room = {
area: 1000,
height: 7,
floor: 2
}
for(let prop in Room) {
console.log(prop);
}
// Result area, height, floor
for(let prop of Room) {
console.log(prop);
}
Room is not iterable
Now for iterating over we need to define an ES6 Symbol.iterator e.g
const Room= {
area: 1000, height: 7, floor: 2,
[Symbol.iterator]: function* (){
yield this.area;
yield this.height;
yield this.floors;
}
}
for(let prop of Room) {
console.log(prop);
}
//Result 1000, 7, 2
This is the difference between For in and For of. Hope that it might clear the difference.
The for-in
loop
for-in
loop is used to traverse through enumerable properties of a collection, in an arbitrary order. A collection is a container type object whose items can be using an index or a key.
var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];
var myString = "123";
console.log( myObject[ 'a' ], myArray[ 1 ], myString[ 2 ] );
for-in
loop extracts the enumerable properties (keys) of a collection all at once and iterates over it one at a time. An enumerable property is the property of a collection that can appear in for-in
loop.
By default, all properties of an Array and Object appear in for-in
loop. However, we can use Object.defineProperty method to manually configure the properties of a collection.
var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];
Object.defineProperty( myObject, 'd', { value: 4, enumerable: false } );
Object.defineProperty( myArray, 3, { value: 4, enumerable: false } );
for( var i in myObject ){ console.log( 'myObject:i =>', i ); }
for( var i in myArray ){ console.log( 'myArray:i =>', i ); }
In the above example, the property d
of the myObject
and the index 3
of myArray
does not appear in for-in
loop because they are configured with enumerable: false
.
There are few issues with for-in
loops. In the case of Arrays, for-in
loop will also consider methods
added on the array using myArray.someMethod = f
syntax, however, myArray.length
remains 4
.
The for-of
loop
It is a misconception that for-of
loop iterate over the values of a collection. for-of
loop iterates over an Iterable
object. An iterable is an object that has the method with the name Symbol.iterator
directly on it one on one of its prototypes.
Symbol.iterator
method should return an Iterator. An iterator is an object which has a next
method. This method when called return value
and done
properties.
When we iterate an iterable object using for-of
loop, the Symbol.iterator
the method will be called once get an iterator object. For every iteration of for-of
loop, next
method of this iterator object will be called until done
returned by the next()
call returns false. The value received by the for-of
loop for every iteration if the value
property returned by the next()
call.
var myObject = { a: 1, b: 2, c: 3, d: 4 };
// make `myObject` iterable by adding `Symbol.iterator` function directlty on it
myObject[ Symbol.iterator ] = function(){
console.log( `LOG: called 'Symbol.iterator' method` );
var _myObject = this; // `this` points to `myObject`
// return an iterator object
return {
keys: Object.keys( _myObject ),
current: 0,
next: function() {
console.log( `LOG: called 'next' method: index ${ this.current }` );
if( this.current === this.keys.length ){
return { done: true, value: null }; // Here, `value` is ignored by `for-of` loop
} else {
return { done: false, value: _myObject[ this.keys[ this.current++ ] ] };
}
}
};
}
// use `for-of` loop on `myObject` iterable
for( let value of myObject ) {
console.log( 'myObject: value => ', value );
}
The for-of
loop is new in ES6 and so are the Iterable and Iterables. The Array
constructor type has Symbol.iterator
method on its prototype. The Object
constructor sadly doesn't have it but Object.keys()
, Object.values()
and Object.entries()
methods return an iterable (you can use console.dir(obj)
to check prototype methods). The benefit of the for-of
loop is that any object can be made iterable, even your custom Dog
and Animal
classes.
The easy way to make an object iterable is by implementing ES6 Generator instead of custom iterator implementation.
Unlike for-in
, for-of
loop can wait for an async task to complete in each iteration. This is achieved using await
keyword after for
statement documentation.
Another great thing about for-of
loop is that it has Unicode support. According to ES6 specifications, strings are stored with UTF-16 encoding. Hence, each character can take either 16-bit
or 32-bit
. Traditionally, strings were stored with UCS-2 encoding which has supports for characters that can be stored within 16 bits
only.
Hence, String.length
returns number of 16-bit
blocks in a string. Modern characters like an Emoji character takes 32 bits. Hence, this character would return length
of 2. for-in
loop iterates over 16-bit
blocks and returns the wrong index
. However, for-of
loop iterates over the individual character based on UTF-16 specifications.
var emoji = "
本文标签:
javascriptDifference between ( for in ) and ( for of ) statementsStack Overflow
版权声明:本文标题:javascript - Difference between ( for... in ) and ( for... of ) statements? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人,
转载请联系作者并注明出处:http://www.betaflare.com/web/1736667870a1946759.html,
本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
for ... of
was brought into the language to fix the problems with usingfor ... in
with Arrays.Array.prototype
could be amended in such a way that extra properties are available, making it unsafe to iterate them as you could get non numeric keys that you weren't expecting. – Phylogenesis Commented Mar 26, 2015 at 18:19of
Keyword (for…of loops), since it asks about a specific behavior of the feature, rather than asking for a general overview. – apsillers Commented Mar 26, 2015 at 18:38for <key> in
" and "for <value> of
" and realize IE doesn't supportfor..of
– BotNet Commented Mar 30, 2018 at 20:54for..of
" While that's technically true, most modern projects use Babel anyway. – Egor Hans Commented Nov 9, 2021 at 8:43