行爲型:迭代器模式

定義

  迭代器模式提供一種方法按順序訪問一個聚合對象中的各個元素,而又不暴露該對象的內部表示。迭代器模式是目的性極強的模式它主要是用來解決遍歷問題。

es6 中的迭代器

  JS原生的集合類型數據結構,有Array(數組)和Object(對象),在ES6中,又新增了Map和Set。四種數據結構各自有着自己的內部實現,但對於使用者,我們希望以同樣的一套規則去遍歷它們,所以ES6在推出新數據結構的同時也推出了一套統一的接口機制——迭代器(Iterator)

  es6 中統一了迭代器迭代接口,任何數據結構只要具備Symbol.iterator屬性(這個屬性就是Iterator的具體實現,它本質上是當前數據結構默認的迭代器生成函數),就可以被遍歷,確切的說是被for...of...循環和迭代器的next方法遍歷,for...of...的背後正是對next方法的反覆調用。

  在ES6中,針對Array、Map、Set、String、TypedArray、函數的 arguments 對象、NodeList 對象這些原生的數據結構都可以通過for...of...進行遍歷。

模擬實現迭代器

  迭代就是不斷的去拿下一個值的一個過程,以及遍歷完的狀態,是否完成遍歷。

閉包寫法

// 定義生成器函數,入參是任意集合
function iteratorGenerator(list) {
    // idx記錄當前訪問的索引
    let idx = 0
    // len記錄傳入集合的長度
    let len = list.length
    return {
        // 自定義next方法
        next: function() {
            // 如果索引還沒有超出集合長度,done爲false
            let done = idx >= len
            // 如果done爲false,則可以繼續取值
            let value = !done ? list[idx++] : undefined
            
            // 將當前值與遍歷是否完畢(done)返回
            return {
                done: done,
                value: value
            }
        }
    }
}

let iterator = iteratorGenerator(['1號選手', '2號選手', '3號選手'])
iterator.next()
iterator.next()
iterator.next()

generator 寫法

在es6 中生成器函數 function * xxx 可以返回生成器對象( Generator 對象由生成器函數返回並且它符合可迭代協議迭代器協議。)

生成器函數在執行時能暫停,後面又能從暫停處繼續執行。

// 生成器函數寫法
function* iteratorGenerator1(list) {
    yield '生成器函數,我是1號'
    yield '生成器函數,我是2號'
    yield '生成器函數,我是3號'
}

let iterator1 = iteratorGenerator1()
console.log(iterator1.next())
console.log(iterator1.next())
console.log(iterator1.next())

// 生成器函數寫法--優化
function* iteratorGenerator2(list) {
    let index = 0, len = list.length;
    while (index <= len - 1) {
        
        yield list[index]
        index++
    }
   
}

let iterator2 = iteratorGenerator2(['生成器函數優化,我是1號', '生成器函數優化,我是2號', '生成器函數優化,我說3號'])
console.log(iterator2.next())
console.log(iterator2.next())
console.log(iterator2.next())

小結

可迭代協議:具備Symbol.iterator

迭代器協議:一個類似這個結構的對象:

{
	next: function () {
 	 return {
   		value: 'xx', // 當前遍歷節點的值
   		done: false  // 是否完成遍歷
    }
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章