1.迭代器是一種特殊的對(duì)象嫉入,它有一個(gè)next()方法浪讳;
每次調(diào)用都會(huì)返回一個(gè)結(jié)果對(duì)象->{done: xxx, value: xxx}虹曙,它有done和value兩個(gè)屬性氓癌。
function createIterator(arr) {
let i = 0
return {
next() {
let done = i >= arr.length
let value = done ? undefined : arr[i++]
return { done, value }
}
}
}
let iterator = createIterator([2,4,6])
console.log(iterator.next()) // {done: false, value: 2}
console.log(iterator.next()) // {done: false, value: 4}
console.log(iterator.next()) // {done: false, value: 6}
console.log(iterator.next()) // {done: true, value: undefined}
2.生成器是一種返回迭代器的函數(shù)滑凉。
不能用箭頭函數(shù)來(lái)創(chuàng)建生成器统扳。(1.標(biāo)準(zhǔn)規(guī)定;2.箭頭函數(shù)是輕量級(jí)應(yīng)用譬涡,類(lèi)似單線(xiàn)程闪幽,不應(yīng)增加包袱)
function *createGenerator(arr) {
for(let i=0; i<arr.length; i++) {
yield arr[i]
}
}
let generator = createGenerator([2,4,6])
console.log(generator.next()) // {done: false, value: 2}
console.log(generator.next()) // {done: false, value: 4}
console.log(generator.next()) // {done: false, value: 6}
console.log(generator.next()) // {done: true, value: undefined}
3.迭代器的作用: 1.循環(huán)內(nèi)部索引跟蹤(迭代器 + for-of循環(huán))
// 不使用迭代器for循環(huán)
let arr = [2,4,6]
for(let i of arr) {
console.log(arr[i])
}
// 1
// 2
// 3
let arr = [2,4,6]
let iterator = arr[Symbol.iterator]() // -> 可迭代的對(duì)象都具有Symbol.iterator屬性
console.log(iterator.next()) // {done: false, value: 2}
console.log(iterator.next()) // {done: false, value: 4}
console.log(iterator.next()) // {done: false, value: 6}
console.log(iterator.next()) // {done: true, value: undefined}
注: 判斷是否為可迭代對(duì)象** -> Symbol.iterator
function isIterable(obj) {
return typeof obj[Symbol.iterator] === 'function'
}
4.內(nèi)建迭代器: ES6中為三種集合對(duì)象Array,Map和Set內(nèi)置了三種迭代器涡匀。
entries() -> 返回鍵值對(duì)
values() -> 返回集合的值
keys() -> 返回集合的鍵
let arr = [1,2,3]
for(let i of arr.entries()){
console.log(i)
}
// [0,1]
// [1,2]
// [2,3]
每一個(gè)集合類(lèi)型都有一個(gè)默認(rèn)的迭代器盯腌,在for-of中,如果沒(méi)有顯示指定則使用默認(rèn)的迭代器陨瘩。
Array和Set集合的默認(rèn)迭代器是values()方法腕够;Map集合的默認(rèn)迭代器是entries()方法。
擴(kuò)展 for-of (只支持Array舌劳,String帚湘,Map,Set甚淡;不支持Object)大诸。
對(duì)于數(shù)組,for-of只遍歷數(shù)字類(lèi)型的索引;for-in遍歷所有屬性资柔。
->創(chuàng)建可迭代對(duì)象
let obj = {
arr: [2,4,6],
*[Symbol.iterator]() {
for(let i of this.arr) {
yield i
}
}
}
for(let i of obj){
console.log(i)
}
// 1
// 2
// 3
5.高級(jí)迭代器功能: 1.給迭代器傳遞參數(shù)焙贷;2.生成器返回語(yǔ)句;3.委托生成器
// 1.給迭代器傳遞參數(shù)
function *createIterator() {
let first = yield 1
let second = yield first + 2
yield second + 3
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
console.log(itetator.next(4)) // {done: false, value: 6} -> 為first賦值贿堰,返回first+2
console.log(itetator.next(5)) // {done: false, value: 8} -> 為second賦值辙芍,返回second+3
console.log(itetator.next()) // {done: true, value: undefined}
// 2.生成器返回語(yǔ)句
function *createIterator() {
yield 1
return 2
yield 3
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
*!console.log(itetator.next()) // {done: true, value: 2}
console.log(itetator.next()) // {done: true, value: undefined}
// 3.委托生成器 - 合并迭代器
function *createNumIterator() {
yield 1
yield 2
}
function *createColorIterator() {
yield 'red'
yield 'green'
}
function *createIterator() {
yield *createNumIterator()
yield *createColorIterator()
yield true
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
console.log(itetator.next()) // {done: false, value: 2}
console.log(itetator.next()) // {done: false, value: 'red'}
console.log(itetator.next()) // {done: false, value: 'green'}
console.log(itetator.next()) // {done: false, value: true}
console.log(itetator.next()) // {done: true, value: undefined}
// 4.委托生成器 - 迭代器間傳值
function *createNumIterator() {
yield 1
yield 2
return 3
}
function *createRepeatIterator(count) {
for(let i = 0; i < count; i++) {
yield 'repeat,' + i
}
}
function *createIterator() {
let result = yield *createNumIterator()
yield *createRepeatIterator(result)
}
let itetator = createIterator()
console.log(itetator.next()) // {done: false, value: 1}
console.log(itetator.next()) // {done: false, value: 2}
console.log(itetator.next()) // {done: false, value: 'repeat, 0'} 注: 不打印3;需要yield result;return只有在最后一個(gè)迭代器中使用才能打印
console.log(itetator.next()) // {done: false, value: 'repeat, 1'}
console.log(itetator.next()) // {done: false, value: 'repeat, 2'}
console.log(itetator.next()) // {done: false, value: undefined}
6.異步任務(wù)執(zhí)行
// 1.向任務(wù)執(zhí)行器傳值
function run(fn) {
let task = fn() // 實(shí)例化生成器
let result = task.next()
function step() {
if(!result.done) {
result = task.next(result.value)
step()
}
}
step()
}
run(function *(){
let value = yield 1
console.log(value) // 1 --> 先執(zhí)行yield 1, 通過(guò)next(result.value), 將result.value-1傳值給let value...
value = yield value + 3
console.log(value) // 4
})
// 2.異步任務(wù)執(zhí)行器
function run(fn) {
let task = fn() // 實(shí)例化生成器
let result = task.next()
function step() {
if(!result.done) {
if(typeof result.value === 'function') {
setTimeout(() => {
let data = result.value(1)
result = task.next(data)
step()
}, 1000)
} else {
setTimeout(() => {
result = task.next(result.value)
step()
}, 1000)
}
}
}
step()
}
function fn(val) {
return val * 2
}
run(function *(){
let value = yield fn
console.log(value) // 2 --> 先執(zhí)行yield fn, 通過(guò)next(result.value), 將result.value-1傳值給let value...
value = yield value + 3
console.log(value) // 5
})