迭代器
🌐 Iterables
如果一个对象实现了 Symbol.iterator 属性,则该对象被视为可迭代的。一些内置类型,如 Array、Map、Set、String、Int32Array、Uint32Array 等,已经实现了它们的 Symbol.iterator 属性。对象上的 Symbol.iterator 函数负责返回用于迭代的值列表。
🌐 An object is deemed iterable if it has an implementation for the Symbol.iterator property.
Some built-in types like Array, Map, Set, String, Int32Array, Uint32Array, etc. have their Symbol.iterator property already implemented.
Symbol.iterator function on an object is responsible for returning the list of values to iterate on.
Iterable 接口
🌐 Iterable interface
Iterable 是一种类型,如果我们想接受上面列出的可迭代类型,就可以使用它。下面是一个例子:
tsfunction toArray<X>(xs: Iterable<X>): X[] {return [...xs]}
for..of 声明
🌐 for..of statements
for..of 遍历一个可迭代对象,并调用对象上的 Symbol.iterator 属性。
下面是一个数组的简单 for..of 循环示例:
tslet 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 返回的是被遍历对象数字属性的 值 列表。
🌐 Both for..of and for..in statements iterate over lists; the values iterated on are different though, for..in returns a list of keys on the object being iterated, whereas for..of returns a list of values of the numeric properties of the object being iterated.
这是一个演示这种区别的示例:
🌐 Here is an example that demonstrates this distinction:
tslet 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 属性,从而可以访问存储的值。
🌐 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 like Map and Set implement Symbol.iterator property allowing access to stored values.
tslet 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 为目标
🌐 Targeting ES5
当针对符合 ES5 的引擎时,迭代器只允许用于 Array 类型的值。即使这些非数组值实现了 Symbol.iterator 属性,在非数组值上使用 for..of 循环也是错误的。
🌐 When targeting an ES5-compliant engine, iterators are only allowed on values of Array type.
It is an error to use for..of loops on non-Array values, even if these non-Array values implement the Symbol.iterator property.
编译器会为 for..of 循环生成一个简单的 for 循环,例如:
🌐 The compiler will generate a simple for loop for a for..of loop, for instance:
tslet numbers = [1, 2, 3];for (let num of numbers) {console.log(num);}
将生成为:
🌐 will be generated as:
jsvar numbers = [1, 2, 3];for (var _i = 0; _i < numbers.length; _i++) {var num = numbers[_i];console.log(num);}
以 ECMAScript 2015 及更高版本为目标
🌐 Targeting ECMAScript 2015 and higher
当以兼容 ECMAScript 2015 的引擎为目标时,编译器将生成 for..of 循环以针对引擎中的内置迭代器实现。
🌐 When targeting an ECMAScript 2015-compliant engine, the compiler will generate for..of loops to target the built-in iterator implementation in the engine.