for...of
语句在可迭代对象(包括 Array
, Map
, Set
, String
, TypedArray
,arguments 对象等等)上创建一个迭代循环,对每个不同属性的属性值,调用一个自定义的有执行语句的迭代挂钩.
语法
for (variable of iterable) { //statements }
variable
- 在每次迭代中,将不同属性的值分配给变量。
- iterable
- 可枚举其枚举属性的对象。
Note: object
例子
迭代 Array
:
let iterable = [10, 20, 30]; for (let value of iterable) {
value += 1;console.log(value); } // 11 // 21 // 31
如果你不修改语句块中的变量 , 也可以使用 const
代替 let
.
let iterable = [10, 20, 30];
for (const value of iterable) {
console.log(value);
}
// 10
// 20
// 30
迭代 String
:
let iterable = "boo";
for (let value of iterable) {
console.log(value);
}
// "b"
// "o"
// "o"
迭代 TypedArray
:
let iterable = new Uint8Array([0x00, 0xff]);
for (let value of iterable) {
console.log(value);
}
// 0
// 255
迭代Map
:
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let entry of iterable) {
console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]
for (let [key, value] of iterable) {
console.log(value);
}
// 1
// 2
// 3
迭代 Set
:
let iterable = new Set([1, 1, 2, 2, 3, 3]);
for (let value of iterable) {
console.log(value);
}
// 1
// 2
// 3
迭代参数对象
(function() {
for (let argument of arguments) {
console.log(argument);
}
})(1, 2, 3);
// 1
// 2
// 3
迭代 DOM 集合
迭代 DOM 元素集合,比如一个NodeList
对象: 下面的例子演示给每一个article标签的p子标签添加一个 "read
" 类.
//注意:这只能在实现了NodeList.prototype [Symbol.iterator]的平台上运行 let articleParagraphs = document.querySelectorAll("article > p"); for (let paragraph of articleParagraphs) { paragraph.classList.add("read"); }
关闭迭代器
对于for...of 的循环,突然的迭代终止可以由break,continue [4],throw或return [5]引起。在这些情况下,迭代器关闭。
function* foo(){
yield 1;
yield 2;
yield 3;
};
for (let o of foo()) {
console.log(o);
break; // closes iterator, triggers return
}
// 1
迭代生成器
您还可以迭代一个 生成器::
function* fibonacci() { // 一个生成器函数 let [prev, curr] = [0, 1]; for (;;) { // while (true) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (let n of fibonacci()) { console.log(n); // 当n大于1000时跳出循环 if (n >= 1000) break; }
不要重用生成器
生成器不应该重用,即使循环的提前终止,例如通过break
关键字。在退出循环后,生成器关闭,并尝试再次迭代,不会产生任何进一步的结果。
var gen = (function *(){ yield 1; yield 2; yield 3; })(); for (let o of gen) { console.log(o); break;//关闭生成器 } //生成器不应该重用,以下没有意义! for (let 0 of gen) { console.log(o); }
迭代另外的可迭代对象
您也可以遍历一个已经明确的可遍历(可迭代)协议。参见 iterable。
var iterable = {
[Symbol.iterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return { value: this.i++, done: false };
}
return { value: undefined, done: true };
}
};
}
};
for (var value of iterable) {
console.log(value);
}
// 0
// 1
// 2
for...of与
for...in的区别
for...in循环会遍历一个object所有的可枚举属性。
for...of语法是为各种collection对象专门定制的,并不适用于所有的object.它会以这种方式迭代出任何拥有[Symbol.iterator]
属性的collection对象的每个元素。
下面的例子演示了for...of
循环和 for...in
循环的区别。for...in
遍历(当前对象及其原型上的)每一个属性名称,而 for...of遍历(当前对象上的)每一个属性值
:
Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};
let iterable = [3, 5, 7];
iterable.foo = "hello";
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
规范
规范 | 状态 | 注释 |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) for...of statement |
Standard | 初始定义 |
ECMAScript Latest Draft (ECMA-262) for...of statement |
Living Standard |
浏览器兼容性
特性 | Chrome | Firefox (Gecko) | Edge | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
基础支持 | 38[1] 51[3] |
13 (13)[2] | 12 | ? | 25 | 7.1 |
特性 | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
基础支持 | ? | 38 [1] | 13.0 (13) [2] | ? | ? | 8 |
[1]从 Chrome 29 到 Chrome 37 这个特性可以在配置之后使用。配置方法:在 chrome://flags/#enable-javascript-harmony 中激活选项“Enable Experimental JavaScript”。
[2] 从Gecko 17 (Firefox 17 / Thunderbird 17 / SeaMonkey 2.14) 到 Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2) 遍历属性可被使用(bug 907077), 从 Gecko 27 到 Gecko 35, "@@iterator"
符号可被使用。在Gecko 36 (Firefox 36 / Thunderbird 36 / SeaMonkey 2.33), @@iterator
symbol 生效 (bug 918828)。
[3] 对遍历对象的支持于 Chrome 51被添加。
相关链接
- for each...in - E4X中的语法,遍历对象的属性值,还不是属性名.
Array.forEach()
- Map.prototype.forEach()