有趣的迭代協議

2021-10-02 09:41:37 字數 2305 閱讀 6166

在vue模板的列表渲染中,有這樣的語法:

在迭代中獲取乙個idx很方便,但是在js的for ... of...迴圈中,我們可以拿到陣列中的一項,但是得到索引卻要費一番功夫。而傳統的基於索引的迴圈,則要多寫一些**。那麼有沒有方法,讓我們在for... of 迴圈中,既能拿到陣列的項,又能拿到索引呢?如下所示:

for (let [item, idx] of list)
答案是肯定的,就是要借助今天的主角,迭代協議了。

迭代器協議(iterator protocol) 定義了一種標準的方式來產生乙個有限或無限序列的值,並且當所有的值都已經被迭代後,就會有乙個預設的返回值。當乙個物件只有滿足下述條件才會被認為是乙個迭代器,它實現了乙個 next() 的方法,而next方法會返回這樣乙個物件:,value表示本次迭代的值,done表示迭代是否結束。根據這個協議,我們可以寫乙個迭代器:

let iterator = 

}return

}}

於是我們可以手動呼叫next()來迭代:

iterator.next()

// iterator.next()

// iterator.next()

//

或者使用while迴圈來迭代:

while(true)
上面的**儘管實現了迭代,卻不能使用for .. of .. 或者[...]這樣的內建語法來迭代。要實現更自然的迭代方式,我們還需要了解可迭代物件協議:為了變成可迭代物件, 乙個物件必須實現 @@iterator 方法, 意思是這個物件(或者它原型鏈 prototype chain 上的某個物件)必須有乙個名字是 symbol.iterator 的屬性

這個也很好理解,因為for...of這樣的語法是為可迭代物件設計的。那麼什麼是可迭代物件呢?打個比方,假如你想35歲以後跑滴滴,那麼首先你必須有一輛車,這時你就被稱為可跑滴滴的人。同理,如果乙個物件有了symbol.iterator 的方法,而且這個方法呼叫後會返回乙個迭代器,這時,這個物件就成了乙個可迭代物件。下面我們來看看怎麼使乙個普通物件變成可迭代的物件。

// 普通物件

let obj =

實現symbol.iterator就可以將普通物件變成可迭代物件:

let obj = 

obj[symbol.iterator] = function()

}return }}

}

這時就可以使用 for...of... 來遍歷obj了?:

for (let [k, v] of obj)
如果你覺得為了要使乙個物件變的可迭代,要自己去理清楚什麼next,done很麻煩,那麼生成器函式就是為你準備的。因為它會返回乙個迭代器:

function* generator() 

let iter = generator();

iter.next() //

iter.next() //

然後我們把obj的symbol.iterator替換成乙個生成器函式:

obj[symbol.iterator] = function*() 

}

這時,你一樣可以使用 for...of...來迭代obj了:

for (let [k, v] of obj)
我們知道可以使用for...of來迭代陣列,字串這些物件,那是因為string, array, typedarray, map, set 都是可迭代物件,他們的原型都實現了 symbol.iterator 方法。文章一開始,我們希望對乙個陣列迭代時,除了拿到它的值以外,還可以拿到他的索引,那我們就需要對[symbol.iterator]方法進行過載修改,我們可以實現乙個reload方法來修改陣列的symbol.iterator方法:

function reload(arr) }}

}var arr = ['x', 'y', 'z']

reload(arr)

for (let [item, idx] of arr)

最後乙個問題:為什麼直接修改array.prototype[symbol.iterator]方法呢?因為解構也用到了迭代協議,那不是我們想要的結果?。有興趣的同學可以試試直接修改原型上的方法

武漢加油!本文完。

python 迭代器協議 Python的迭代器協議

迭代器是python中的乙個高階概念,迭代器是乙個實現了迭代器協議的物件,那何為迭代器協議呢?滿足下面兩個條件就行。1 該物件實現了 iter 方法 2 該物件實現了next 方法,返回當前元素,並指向下乙個元素的位置,如果當前位置已無元素,則丟擲stopiteration異常。看下面例子 這說明列...

迭代器協議

l list hello 這就是在做例項化,list是乙個類 for i in l 先將乙個物件執行 iter print i class foo def init self,n self.n n def iter self return self def next self if self.n 1...

Python 滿足迭代協議的可迭代物件

python 可迭代物件 迭代 迭代工具 for.推導.map等 滿足迭代協議f.next 迭代物件分為 1.可直接用迭代協議迭代的迭代器物件,如文字 2.可以迭代的物件,但需要用iter 函式生成迭代協議形成迭代器物件,再用迭代協議迭代,如for list a jdiejwi0 mwiejf di...