可遍历(Iterables)
如果一个对象实现了 Symbol.iterator 属性,那么它就是可遍历的。Array、Map、Set、String、Int32Array、Unit32Array 等内置类型都已经实现了 Symbol.iterator 属性。该属性是一个函数,负责返回可供遍历的值的列表。
Iterable 接口(Iterable interface)
Iterable 是一个类型,可以用来标记可遍历的类型,比如上面列出来的 Array、Map 等。
function toArray<X>(xs: Iterable<X>): X[] {return [...xs]}
for..of 声明(for..of statements)
for..of 用来遍历可遍历对象,调用它们的 Symbol.iterator 属性。下面是一个使用 for..of 遍历数组的例子:
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
for..of 与 for..in 声明的比较(for..of vs. for..in statements)
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
}
另一个区别是 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"
}
代码生成(Code generation)
以 ES5 和 ES3 为目标(Targeting ES5 and ES3)
当编译目标是 ES5 或者兼容 ES3 的引擎时,只可以遍历 Array 类型的值。当使用 for..of 遍历非数组对象时会报错,即使它实现了 Symbol.iterator 接口。
编译器会将 for..of 编译为简单的 for 循环。
let numbers = [1, 2, 3];
for (let num of numbers) {
console.log(num);
}
上述代码的编译结果为:
var numbers = [1, 2, 3];
for (var _i = 0; _i < numbers.length; _i++) {
var num = numbers[_i];
console.log(num);
}
以 ECMAScript 2015 或者更高版本为目标(Targeting ECMAScript2015 and higher)
当编译目标时 ECMAScript2015 或者更高版本的引擎时,编译器会将 for..of 转换为目标引擎的默认实现。
