提问人:Mukund Kumar 提问时间:3/27/2015 最后编辑:Top-MasterMukund Kumar 更新时间:9/13/2023 访问量:713502
( for...in ) 和 ( for...的)语句?
Difference between ( for... in ) and ( for... of ) statements?
问:
我知道什么是循环(它遍历键),但我第一次听说过(它遍历值)。for... in
for... of
我对循环感到困惑。for... of
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"
}
我知道迭代属性值。那为什么它不记录而不是?for... of
"3", "5", "7", "hello"
"3", "5", "7"
与循环不同,循环遍历每个键 () 并遍历键,而 the 不会遍历属性的值,即 .为什么会这样?for... in
"0", "1", "2", "foo"
foo
for... of
foo
"hello"
在这里,我控制台循环。它应该记录,但它记录.为什么?for... of
"3", "5", "7","hello"
"3", "5", "7"
答:
for 在
对象的可枚举属性名称上循环。
for
(ES6 中的新功能)确实使用特定于对象的迭代器并循环访问由它生成的值。
在示例中,数组迭代器确实会生成数组中的所有值(忽略非索引属性)。
评论
for... of
for..
of..
for..in..keys
for...in
for...of
in
给你索引。这足以记住差异。如果你在其他方面应用逻辑。
我在 Iterators and Generators 中找到了完整的答案(虽然它适用于 TypeScript,但 JavaScript 也是如此)
和 语句都遍历列表;价值观 迭代是不同的,但返回一个键列表 正在迭代的对象,而返回值列表 被迭代对象的数值属性。
for..of
for..in
for..in
for..of
下面是一个示例来证明这种区别:
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" }
另一个区别是对任何对象进行操作;它服务 作为检查此对象的属性的一种方式。 另一方面 hand,主要对可迭代对象的值感兴趣。内置 对象,如 和 实现属性允许 访问存储的值。
for..in
for..of
Map
Set
Symbol.iterator
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" }
评论
index
values
let thisItem = items[all];
for...of
for...in
Number(i)
for-in 语句按任意顺序循环访问对象的可枚举属性。
该循环将遍历对象本身的所有可枚举属性以及对象从其构造函数的原型继承的属性
你可以把它想象成“for in”基本上迭代并列出所有键。
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"]
评论
for in
只有在我们添加的键时才会显示它们,它不会显示 formatUnicorn
String.prototype
为。。。在环中
为了...In Loop 通过消除计数逻辑和退出条件来改进 FOR 循环的弱点。
例:
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
console.log(digits[index]);
}
但是,您仍然必须处理使用索引来访问数组值的问题,这很臭;这几乎使它比以前更加混乱。
此外,对于...当您需要向数组(或其他对象)添加额外的方法时,in 循环可能会给您带来大麻烦。因为为了...在循环中循环所有可枚举属性,这意味着如果向数组的原型添加任何其他属性,则这些属性也将出现在循环中。
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]);
}
指纹:
0
1
2
3
4
5
6
7
8
9
函数() { for (let i = 0; i < this.length; i++) { this[i] = this[i].toFixed(2); } }
这就是为什么...在数组上循环时,不建议使用 In 循环。
注意:forEach 循环是 JavaScript 中另一种类型的 for 循环。 但是,
forEach()
实际上是一个数组方法,所以它只能使用 仅与数组一起使用。也没有办法停止或打破一个 forEach 循环。如果你在循环中需要这种类型的行为,你将 必须使用基本的 for 循环。
为。。。的循环
为了...of 循环用于循环遍历任何类型的可迭代数据。
例:
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
console.log(digit);
}
指纹:
0
1
2
3
4
5
6
7
8
9
这使得...of 循环是所有 for 循环中最简洁的版本。
但是等等,还有更多!为了...of 循环还具有一些额外的好处,可以修复 for 和 for 的弱点......在循环中。
您可以停止或中断...的循环。
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);
}
指纹:
1
3
5
7
9
而且您不必担心向对象添加新属性。为了...of 循环将仅循环访问对象中的值。
评论
for (var index=0; index<arr.length; index++)
index
索引
是一个字符串。它既不是计数器也不是整数,这在很大程度上是一个问题。只是永远不要用于...在
数组的枚举中!for (const index in digits)
为了...in
语句按任意顺序循环访问对象的可枚举属性。
可枚举属性是其内部 [[Enumerable]] 标志设置为 true 的那些属性,因此,如果原型链中有任何可枚举属性,循环也会迭代这些属性。for...in
为了...of
语句循环访问可迭代对象定义要迭代的数据。
例:
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
}
与之前一样,您可以跳过添加循环。hasOwnProperty
for...of
有一些已经定义的数据类型允许我们轻松地迭代它们,例如数组、地图、字符串对象
Normal for in 遍历迭代器和 in 响应,为我们提供按插入顺序排列的键,如以下示例所示。
const numbers = [1,2,3,4,5];
for(let number in number) {
console.log(number);
}
// result: 0, 1, 2, 3, 4
现在,如果我们尝试与 for of 相同,那么作为响应,它为我们提供了值而不是键。例如
const numbers = [1,2,3,4,5];
for(let numbers of numbers) {
console.log(number);
}
// result: 1, 2, 3, 4, 5
因此,查看这两个迭代器,我们可以很容易地区分它们之间的区别。
注意:- for only works with Symbol.iterator
因此,如果我们尝试遍历普通对象,那么它将给我们一个错误,例如-
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);
}
房间不可迭代
现在为了迭代,我们需要定义一个 ES6 Symbol.iterator,例如
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
这就是 For in 和 For of 之间的区别。希望它能消除差异。
评论
每个人都解释了为什么会出现这个问题,但仍然很容易忘记它,然后挠头为什么你得到了错误的结果。尤其是当您处理大型数据集时,乍一看结果似乎很好。
使用您确保遍历所有属性:Object.entries
var arr = [3, 5, 7];
arr.foo = "hello";
for ( var [key, val] of Object.entries( arr ) ) {
console.log( val );
}
/* Result:
3
5
7
hello
*/
区别和:for..in
for..of
两者都是循环构造,用于循环访问数据结构。它们之间的唯一区别是实体
他们迭代:for..in
for..of
for..in
循环访问对象的所有可枚举属性键for..of
循环访问可迭代对象的值。可迭代对象的示例包括数组、字符串和 NodeLists。
例:
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)
}
在这个例子中,我们可以观察到循环遍历对象的键,在这个例子中,对象是一个数组对象。键是 0、1、2(对应于数组元素)和 .这是数组对象在 chrome devtools 中的样子:for..in
addedProp
arr
你可以看到,我们的循环只不过是简单地遍历这些键。for..in
我们示例中的循环循环访问数据结构的值。此特定示例中的值为 。可迭代数据结构将使用的值取决于可迭代对象的类型。例如,数组将返回所有数组元素的值,而字符串将返回字符串的每个字符。for..of
'el1', 'el2', 'el3'
for..of
评论
for..of
看到很多好的答案,但我决定把我的 5 美分只是为了有个好例子:
For 在环
遍历所有可枚举的道具
let nodes = document.documentElement.childNodes;
for (var key in nodes) {
console.log( key );
}
For of 循环
遍历所有可迭代值
let nodes = document.documentElement.childNodes;
for (var node of nodes) {
console.log( node.toString() );
}
两个循环之间的另一个区别,以前没有人提到过:
不推荐使用解构。请改用。
for...in
for...of
因此,如果我们想在循环中使用解构,为了获取每个数组元素的索引和值,我们应该将循环与 Array 方法 entries()
一起使用:for...of
for (const [idx, el] of arr.entries()) {
console.log( idx + ': ' + el );
}
评论
for each...in
for...in
for...of
循环for-in
for-in
Loop 用于按任意顺序遍历集合的可枚举属性。集合是一个容器类型的对象,其项可以使用索引或键。
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 一次性提取集合的可枚举属性(键),并逐个循环访问它。可枚举属性是可以在循环中出现的集合的属性。for-in
默认情况下,Array 和 Object 的所有属性都显示在循环中。但是,我们可以使用 Object.defineProperty 方法来手动配置集合的属性。for-in
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 ); }
在上面的示例中,和 的 索引的属性不会出现在循环中,因为它们配置了 .d
myObject
3
myArray
for-in
enumerable: false
循环几乎没有问题。在数组的情况下,loop 也会考虑使用语法添加到数组上,但是,仍然存在。for-in
for-in
methods
myArray.someMethod = f
myArray.length
4
循环for-of
循环迭代集合的值是一种误解。 循环遍历对象。可迭代对象是一个对象,其方法的名称直接在其上,在其原型之一上。for-of
for-of
Iterable
Symbol.iterator
Symbol.iterator
方法应返回一个迭代器。迭代器是具有方法的对象。此方法在调用 return 和 properties 时。next
value
done
当我们使用循环迭代一个可迭代对象时,一旦得到一个迭代器对象,就会调用该方法。对于循环的每次迭代,都会调用此迭代器对象的方法,直到调用返回 false 为止。如果调用返回属性,则循环在每次迭代中接收的值。for-of
Symbol.iterator
for-of
next
done
next()
for-of
value
next()
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 );
}
循环是 ES6 中的新循环,Iterable 和 Iterable 也是如此。构造函数类型在其原型上有方法。遗憾的是,构造函数没有它,但是 ,并且方法返回一个可迭代对象(您可以使用 console.dir(obj)
来检查原型方法)。循环的好处是可以使任何对象都可迭代,甚至是您的自定义和类。for-of
Array
Symbol.iterator
Object
Object.keys()
Object.values()
Object.entries()
for-of
Dog
Animal
使对象可迭代的简单方法是实现 ES6 Generator,而不是自定义迭代器实现。
与 不同,循环可以在每次迭代中等待异步任务完成。这是在语句文档后使用关键字来实现的。for-in
for-of
await
for
loop 的另一个优点是它支持 Unicode。根据 ES6 规范,字符串以 UTF-16 编码存储。因此,每个字符都可以取 或 。传统上,字符串是用 UCS-2 编码存储的,该编码支持只能存储在其中的字符。for-of
16-bit
32-bit
16 bits
因此,返回字符串中的块数。像表情符号字符这样的现代字符需要 32 位。因此,此字符将返回 2。 循环遍历块并返回错误的 .但是,循环会根据 UTF-16 规范循环访问单个字符。String.length
16-bit
length
for-in
16-bit
index
for-of
var emoji = "😊🤣";
console.log( 'emoji.length', emoji.length );
for( var index in emoji ){ console.log( 'for-in: emoji.character', emoji[index] ); }
for( var character of emoji ){ console.log( 'for-of: emoji.character', character ); }
当我第一次开始学习 for in 和 of 循环时,我也对我的输出感到困惑,但通过一些研究和理解,您可以像这样思考单个循环: 这
- 为。。。in 循环返回单个属性的索引,并且对属性的值没有影响,它循环并返回有关属性而不是值的信息。 例如
let profile = {
name : "Naphtali",
age : 24,
favCar : "Mustang",
favDrink : "Baileys"
}
上面的代码只是创建了一个名为 profile 的对象,我们将在两个示例中使用它,因此,当您在示例中看到 profile 对象时不要感到困惑,只需知道它是创建的。
所以现在让我们使用 for...在下面循环
for(let myIndex in profile){
console.log(`The index of my object property is ${myIndex}`)
}
// Outputs :
The index of my object property is 0
The index of my object property is 1
The index of my object property is 2
The index of my object property is 3
现在输出的原因是我们的配置文件对象中有四(4)个属性,并且我们都知道索引从0...n开始,因此,我们得到了属性0,1,2,3的索引,因为我们正在使用for.。在循环中。
为。。。of loop* 可以返回属性、值或两者兼而有之,让我们来看看如何。 在 javaScript 中,我们不能像在数组上那样正常地遍历对象,因此,我们可以使用一些元素来访问对象中的任一选择。
Object.keys(object-name-goes-here) >>> 返回对象的键或属性。
Object.values(object-name-goes-here) >>> 返回对象的值。
- Object.entries(object-name-goes-here) >>> 返回对象的键和值。
以下是它们的用法示例,请注意 Object.entries() :
Step One: Convert the object to get either its key, value, or both.
Step Two: loop through.
// Getting the keys/property
Step One: let myKeys = ***Object.keys(profile)***
Step Two: for(let keys of myKeys){
console.log(`The key of my object property is ${keys}`)
}
// Getting the values of the property
Step One: let myValues = ***Object.values(profile)***
Step Two : for(let values of myValues){
console.log(`The value of my object property is ${values}`)
}
使用 Object.entries() 时,您正在调用对象上的两个条目,即键和值。您可以通过任一条目调用两者。下面的例子。
Step One: Convert the object to entries, using ***Object.entries(object-name)***
Step Two: **Destructure** the ***entries object which carries the keys and values***
like so **[keys, values]**, by so doing, you have access to either or both content.
// Getting the keys/property
Step One: let myKeysEntry = ***Object.entries(profile)***
Step Two: for(let [keys, values] of myKeysEntry){
console.log(`The key of my object property is ${keys}`)
}
// Getting the values of the property
Step One: let myValuesEntry = ***Object.entries(profile)***
Step Two : for(let [keys, values] of myValuesEntry){
console.log(`The value of my object property is ${values}`)
}
// Getting both keys and values
Step One: let myBothEntry = ***Object.entries(profile)***
Step Two : for(let [keys, values] of myBothEntry){
console.log(`The keys of my object is ${keys} and its value
is ${values}`)
}
对不清楚的部分进行评论。
评论
这是一个有用的助记符,用于记住 Loop 和 Loop 之间的区别。for...in
for...of
“索引,对象”
for...in Loop
=> 遍历数组中的索引。
for...of Loop
=> 遍历对象的对象。
评论
为。。。of 循环仅适用于可迭代对象。在 JavaScript 中,可迭代对象是可以循环的对象。
String、Array、TypedArray、Map 和 Set 都是内置的可迭代对象,因为它们的每个原型对象都实现了一个@@iterator方法。所以,为了...of 循环适用于上述对象类型。
默认情况下,JavaScript 中的对象是不可迭代的。所以,为了...of 循环不适用于对象。
简单来说,为了...of 适用于字符串和数组,但不适用于对象。
为。。。适用于其 Enumerable 标志设置为 true 的那些属性。
默认情况下,通过简单赋值或属性初始值设定项创建的属性的可枚举标志为 true。 默认情况下,通过 Object.defineProperty 创建的属性的可枚举标志为 false。
以下是带有示例的更详细的帖子: https://dev.to/swastikyadav/difference-between-forof-and-forin-loop-in-javascript-j2o
简短的回答:循环键,而循环值。for...in
for...of
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
对于 in,迭代对象中的键并在数组中编制索引
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,迭代数组或任何可迭代对象中的值
let arr = [10, 11, 12, 13];
for (const item of arr )
console.log(item); //would print 10 11 12 13
for of
用于循环访问可迭代对象,并用于循环访问对象属性for in
这里有一个要记住的技巧:
for of
不适用于 objects(所以它适用于可迭代对象)
for in
不是针对 Iterables(所以它适用于对象)
另一个技巧:
for in
在骰子(键)中返回对象,同时返回值for of
评论
简单来说,forIN 遍历 array(index)/object(key) 中的 KEYS,
而 forOF 遍历 array(value) 的 VALUES U。
请记住,它用于对象,而用于数组、字符串等。for in
for of
但是,您甚至不需要使用 .您可以随时改用:for in
for of
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
}
像这样的唯一数据构造函数通常用于或替代地创建 .BRRR的obfuscators
<cencored>
var arr = [3, 5, 7];
arr.foo = "hello";
console.log(typeof arr) // object
console.log(Object.keys(arr)) // ["0", "1", "2", "foo"]
console.log(Object.values(arr)) // ["3", "5", "7", "hello"]
// console.log(Object.entries(arr))
for (var index in arr) {
console.log(index); // logs "0", "1", "2", "foo"
}
for (var value of arr) {
console.log(value); // logs "3", "5", "7"
}
for (var objValue of Object.values(arr)) {
console.log(objValue); // logs "3", "5", "7", "hello"
}
简单的答案是..的,你可以在里面使用异步,而for..在没有。
评论
for ... of
for ... in
Array.prototype
的
JavaScript 的副本(对于...的循环),因为它询问功能的特定行为,而不是询问一般概述。for <key> in
for <value> of
for..of
for..of