JS之Iterations
for in、for of、for each in
1.for in:用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作),for ... in 循环中的代码每执行一次,就会对数组的元素或者对象的属性进行一次操作,for...in语句以任意顺序遍历一个对象的可枚举属性,对于每个不同的属性,语句都会被执行。
for (variable in object) { }
variable:在每次迭代时,将不同的属性名分配给变量;object:被迭代枚举其属性的对象。
一个for...in
仅环比枚举,非符号属性迭代。对象从内置构造等生成Array
和Object
继承来自非枚举的属性Object.prototype
和String.prototype
诸如String的indexOf()方法或object的toString()方法。循环将遍历对象本身的所有可枚举属性以及对象从其构造函数的原型继承的属性(更靠近原型链中对象的属性覆盖原型的属性)。
注意: for...in
不应该用于迭代Array索引顺序很重要的位置。
数组索引只是具有整数名称的枚举属性,并且与通用对象属性相同。不能保证for ... in
将以任何特定的顺序返回索引。for ... in
循环语句将返回所有可枚举属性,包括非整数类型的名称和继承的那些。因为迭代的顺序是依赖于实现的,所以迭代数组可能不会以一致的顺序访问元素。因此,在迭代访问顺序很重要的数组时,最好使用for带有数字索引(或循环)Array.prototype.forEach()
的for...of
循环。
for-in循环实际是为循环”enumerable“对象而设计的
1 let obj = {a: '1', b: '2', c: '3', d: '4'} 2 for (let o in obj) { 3 console.log(o) //遍历的实际上是对象的属性名称 a,b,c,d 4 console.log(obj[o]) //这个才是属性对应的值1,2,3,4 5 }
2.for of:创建了一个循环迭代迭代的对象(包括内置的String
,Array
例如该Array
式的arguments
或NodeList
对象,TypedArray
,Map
和Set
,和用户定义的iterables),调用的自定义迭代钩与语句来为每个不同的属性的值执行对象。
for (variable of iterable) { statement }
variable:
在每次迭代时,将不同属性的值分配给变量;iterable:
迭代其可迭代属性的对象。
(1)循环一个数组(Array
):
1 let iterable = [10, 20, 30]; 2 3 for (let value of iterable) { 4 console.log(value); 5 } 6 // 10 7 // 20 8 // 30
我们可以使用const
来替代let
,这样它就变成了在循环里的不可修改的静态变量。
1 let iterable = [10, 20, 30]; 2 3 for (const value of iterable) { 4 console.log(value); 5 } 6 // 10 7 // 20 8 // 30
(2)循环一个字符串:
let iterable = "boo"; for (let value of iterable) { console.log(value); } // "b" // "o" // "o"
(3)循环一个类型化的数组(TypedArray
):
let iterable = new Uint8Array([0x00, 0xff]); for (let value of iterable) { console.log(value); } // 0 // 255
(4)循环一个Map
:
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]); for (let [key, value] of iterable) { console.log(value); } // 1 // 2 // 3 for (let entry of iterable) { console.log(entry); } // [a, 1] // [b, 2] // [c, 3]
(5)循环一个 Set
:
let iterable = new Set([1, 1, 2, 2, 3, 3]); for (let value of iterable) { console.log(value); } // 1 // 2 // 3
(6)循环一个 DOM collection
// Note: This will only work in platforms that have // implemented NodeList.prototype[Symbol.iterator] let articleParagraphs = document.querySelectorAll("article > p"); for (let paragraph of articleParagraphs) { paragraph.classList.add("read"); }
(7)循环一个拥有enumerable属性的对象
for–of循环并不能直接使用在普通的对象上,但如果我们按对象所拥有的属性进行循环,可使用内置的Object.keys()方法:
for (var key of Object.keys(someObject)) { console.log(key + ": " + someObject[key]); }
(8)循环一个生成器(generators)
function* fibonacci() { // a generator function let [prev, curr] = [0, 1]; while (true) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (let n of fibonacci()) { console.log(n); // truncate the sequence at 1000 if (n >= 1000) { break; } }
3.for each in: 该语句在对象属性的所有值上迭代指定的变量。对于每个不同的属性,执行指定的语句。
for each (variable in object) { statement }
variable:
变量以迭代属性值,可选地使用var
关键字声明。该变量是函数的本地变量,而不是循环。object:
迭代属性的对象。
statement:
要为每个属性执行的语句。要在循环中执行多个语句,请使用block语句({ ... }
)对这些语句进行分组。
警告:永远不要在数组上使用这样的循环。仅在物体上使用它。以下代码段迭代对象的属性,计算它们的总和:
var sum = 0; var obj = {prop1: 5, prop2: 13, prop3: 8}; for each (var item in obj) { sum += item; } console.log(sum); // logs "26", which is 5+13+8