警告 此服務(wù)器美國(guó)維護(hù)搜外seo視頻 網(wǎng)絡(luò)營(yíng)銷免費(fèi)視頻課程
Iterator迭代器和for/of循環(huán)原理
Iterator迭代器規(guī)范
自己創(chuàng)建一個(gè)Iterator類,來(lái)實(shí)現(xiàn)ES6中的迭代器規(guī)范:
class Iterator {constructor(assemble) {// assemble:需要迭代的數(shù)據(jù)結(jié)構(gòu)this.assemble = assemble// index:記錄迭代的次數(shù)(或者索引)this.index = -1}// 必須具備next方法next() {this.index++let { assemble, index } = thisif (index >= assemble.length) {// 迭代完畢return {done: true,value: undefined}}return {done: false,value: assemble[index]}}
}
創(chuàng)建一個(gè)實(shí)例對(duì)象,其應(yīng)該符合迭代器規(guī)范的要求:
- itor.next() 具備next方法,執(zhí)行這個(gè)方法可以依次遍歷數(shù)據(jù)結(jié)構(gòu)中的每一個(gè)成員
- 每一次遍歷返回的結(jié)果是一個(gè)對(duì)象
{done:false,value:xxx}
- done: 是否迭代完畢
- value: 當(dāng)前獲取的成員值
符合以上兩個(gè)特點(diǎn)的對(duì)象,我們稱之為符合迭代器規(guī)范的對(duì)象
let arr = [10, 20, 30, 40],itor = new Iterator(arr)
console.log(itor.next()) // {done: false, value: 10}
console.log(itor.next()) // {done: false, value: 20}
console.log(itor.next()) // {done: false, value: 30}
console.log(itor.next()) // {done: false, value: 40}
console.log(itor.next()) // {done: true, value: undefined}
在JS中,有很多數(shù)據(jù)結(jié)構(gòu),天生具備迭代器規(guī)范,例如:
我們主要看數(shù)據(jù)結(jié)構(gòu)(對(duì)象)是否具備 Symbol.iterator 這個(gè)屬性;有這個(gè)屬性就具備迭代器規(guī)范,沒(méi)有就不具備;具備這個(gè)規(guī)范,就可以使用 for/of 循環(huán)來(lái)迭代數(shù)據(jù)中的每一項(xiàng)值了。
- 數(shù)組 Array.prototype[Symbol(Symbol.iterator)]=function…
- 部分類數(shù)組:
- arguments[Symbol(Symbol.iterator)]
- NodeList.prototype[Symbol(Symbol.iterator)]
document.querySelectorAll('*')
- HTMLCollection.prototype[Symbol(Symbol.iterator)]
document.getElementsByTagName('*')
- …
- 字符串 String.prototype[Symbol(Symbol.iterator)]
- Set/Map
- …
但是對(duì)于純粹對(duì)象「或者自己構(gòu)建的類數(shù)組對(duì)象(以數(shù)字作為索引,索引從0開(kāi)始逐級(jí)遞增,有l(wèi)ength屬性表示長(zhǎng)度)」等來(lái)講,默認(rèn)是不具備 Symbol.iterator 這個(gè)屬性的,所以他們不具備迭代器規(guī)范「不能直接使用 for/of 循環(huán)」
for/of循環(huán)原理
重寫(xiě)數(shù)組迭代器規(guī)范(數(shù)組有內(nèi)置的迭代器規(guī)范)來(lái)說(shuō)明原理:
// 數(shù)組迭代的方式 for、while、forEach/map、for/in、for/of...
let array = [10, 20, 30, 40]
array[Symbol.iterator] = function () {console.log('for/of Start');let self = this,// this->arrayindex = -1// 返回具備迭代器規(guī)范的對(duì)象->itorrreturn {next() {index += 2if (index >= self.length) {return {done: true,value: undefined}}return {done: false,value: self[index]}}}
}
// let itorr = array[Symbol.iterator]()
for (let val of array) {console.log(val);
}
// for/of循環(huán)主要用于獲取數(shù)據(jù)結(jié)構(gòu)中每一項(xiàng)的‘值’
for (let val of array) {console.log(val);
}
原理:
1.迭代執(zhí)行,先執(zhí)行數(shù)組的 Symbol.iterator 這個(gè)方法,獲取一個(gè)具備迭代器規(guī)范的對(duì)象 -> itor
2.開(kāi)始迭代:每一次迭代都是把 itor.next 方法執(zhí)行
- 把獲取對(duì)象中的value屬性值,賦值給val這個(gè)變量
- 再看對(duì)象中done這個(gè)屬性的值,如果是false,則繼續(xù)迭代;如果是true,則結(jié)束迭代
普通對(duì)象是不具備迭代器規(guī)范的:
let obj = {name: '52lkk',age: 24,0: 100,[Symbol('AA')