- ES6 教程
- ES6 - 首頁
- ES6 - 概述
- ES6 - 環境
- ES6 - 語法
- ES6 - 變數
- ES6 - 運算子
- ES6 - 決策
- ES6 - 迴圈
- ES6 - 函式
- ES6 - 事件
- ES6 - Cookies
- ES6 - 頁面重定向
- ES6 - 對話方塊
- ES6 - Void 關鍵字
- ES6 - 頁面列印
- ES6 - 物件
- ES6 - 數字
- ES6 - 布林值
- ES6 - 字串
- ES6 - Symbol
- ES6 - 新的字串方法
- ES6 - 陣列
- ES6 - 日期
- ES6 - 數學
- ES6 - 正則表示式
- ES6 - HTML DOM
- ES6 - 迭代器
- ES6 - 集合
- ES6 - 類
- ES6 - Map 和 Set
- ES6 - Promise
- ES6 - 模組
- ES6 - 錯誤處理
- ES6 - 物件擴充套件
- ES6 - Reflect API
- ES6 - Proxy API
- ES6 - 驗證
- ES6 - 動畫
- ES6 - 多媒體
- ES6 - 除錯
- ES6 - 影像地圖
- ES6 - 瀏覽器
- ES7 - 新特性
- ES8 - 新特性
- ES9 - 新特性
- ES6 有用資源
- ES6 - 快速指南
- ES6 - 有用資源
- ES6 - 討論
ES6 - 迭代器
迭代器介紹
迭代器是一個物件,它允許我們一次訪問一個物件的集合。
以下內建型別預設情況下是可迭代的 -
- 字串
- 陣列
- Map
- Set
如果一個物件實現了一個鍵為[Symbol.iterator]並返回迭代器的函式,則該物件被認為是可迭代的。可以使用 for...of 迴圈來迭代集合。
示例
以下示例宣告一個數組 marks,並使用for..of迴圈遍歷它。
<script>
let marks = [10,20,30]
//check iterable using for..of
for(let m of marks){
console.log(m);
}
</script>
以上程式碼的輸出將如下所示 -
10 20 30
示例
以下示例宣告一個數組 marks 並檢索一個迭代器物件。[Symbol.iterator]()可用於檢索迭代器物件。迭代器的 next() 方法返回一個包含'value'和'done'屬性的物件。'done' 是布林值,在讀取集合中的所有專案後返回 true。
<script> let marks = [10,20,30] let iter = marks[Symbol.iterator](); console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) </script>
以上程式碼的輸出將如下所示 -
{value: 10, done: false}
{value: 20, done: false}
{value: 30, done: false}
{value: undefined, done: true}
自定義可迭代物件
JavaScript 中的某些型別是可迭代的(例如 Array、Map 等),而其他型別則不是(例如 Class)。預設情況下不可迭代的 JavaScript 型別可以透過使用可迭代協議進行迭代。
以下示例定義了一個名為CustomerList的類,它將多個客戶物件儲存為一個數組。每個客戶物件都具有 firstName 和 lastName 屬性。
為了使此類可迭代,該類必須實現[Symbol.iterator]()函式。此函式返回一個迭代器物件。迭代器物件有一個函式next,它返回一個物件{value:'customer',done:true/false}。
<script>
//user defined iterable
class CustomerList {
constructor(customers){
//adding customer objects to an array
this.customers = [].concat(customers)
}
//implement iterator function
[Symbol.iterator](){
let count=0;
let customers = this.customers
return {
next:function(){
//retrieving a customer object from the array
let customerVal = customers[count];
count+=1;
if(count<=customers.length){
return {
value:customerVal,
done:false
}
}
//return true if all customer objects are iterated
return {done:true}
}
}
}
}
//create customer objects
let c1={
firstName:'Sachin',
lastName:'Tendulkar'
}
let c2={
firstName:'Rahul',
lastName:'Dravid'
}
//define a customer array and initialize it let customers=[c1,c2]
//pass customers to the class' constructor
let customersObj = new CustomerList(customers);
//iterating using for..of
for(let c of customersObj){
console.log(c)
}
//iterating using the next() method
let iter = customersObj[Symbol.iterator]();
console.log(iter.next())
console.log(iter.next())
console.log(iter.next())
</script>
以上程式碼的輸出如下所示 -
{firstName: "Sachin", lastName: "Tendulkar"}
{firstName: "Rahul", lastName: "Dravid"}
{
done: false
value: {
firstName: "Sachin",
lastName: "Tendulkar"
}
}
{
done: false
value: {
firstName: "Rahul",
lastName: "Dravid"
}
}
{done: true}
生成器
在 ES6 之前,JavaScript 中的函式遵循執行至完成模型。ES6 引入了稱為生成器的函式,這些函式可以在中途停止,然後從停止的地方繼續。
生成器在函式名字首一個星號 * 字元,幷包含一個或多個yield語句。yield關鍵字返回一個迭代器物件。
語法
function * generator_name() {
yield value1
...
yield valueN
}
示例
該示例定義了一個生成器函式getMarks,其中包含三個 yield 語句。與普通函式不同,生成器函式 getMarks()在呼叫時不會執行函式,而是返回一個迭代器物件,該物件可幫助您執行生成器函式內的程式碼。
在第一次呼叫markIter.next()時,開頭的操作將執行,並且 yield 語句會暫停生成器的執行。後續對markIter.next()的呼叫將恢復生成器函式,直到下一個yield表示式。
<script>
//define generator function
function * getMarks(){
console.log("Step 1")
yield 10
console.log("Step 2")
yield 20
console.log("Step 3")
yield 30
console.log("End of function")
}
//return an iterator object
let markIter = getMarks()
//invoke statements until first yield
console.log(markIter.next())
//resume execution after the last yield until second yield expression
console.log(markIter.next())
//resume execution after last yield until third yield expression
console.log(markIter.next())
console.log(markIter.next()) // iteration is completed;no value is returned
</script>
以上程式碼的輸出將如下所示 -
Step 1
{value: 10, done: false}
Step 2
{value: 20, done: false}
Step 3
{value: 30, done: false}
End of function
{value: undefined, done: true}
示例
以下示例透過
* evenNumberGenerator 生成器函式建立了一個無限的偶數序列。
我們可以使用next()或使用for of迴圈遍歷所有偶數,如下所示
<script>
function * evenNumberGenerator(){
let num = 0;
while(true){
num+=2
yield num
}
}
// display first two elements
let iter = evenNumberGenerator();
console.log(iter.next())
console.log(iter.next())
//using for of to iterate till 12
for(let n of evenNumberGenerator()){
if(n==12)break;
console.log(n);
}
</script>
以上程式碼的輸出如下所示 -
{value: 2, done: false}
{value: 4, done: false}
2
4
6
8
10