日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入理解ES6之迭代器与生成器

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解ES6之迭代器与生成器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

迭代器

迭代器 iterator,在 Javascript 中,迭代器是一個對象(也可稱作為迭代器對象),它提供了一個 next() 方法,用來返回迭代序列中的下一項。

next 方法的定義,next 方法是一個函數,執行后返回一個對象包含兩個屬性:{ done: [boolean], value: [any] }

function makeIterator(array) {var nextIndex = 0return {next() {return nextIndex < array.length ? { value: array[nextIndex++], done: false } : { done: true }}} }// iterator 是一個迭代器對象 var iterator = makeIterator([10, 20, 30]) iterator.next() // {value: 10, done: false} iterator.next() // {value: 20, done: false} iterator.next() // {value: 30, done: false} iterator.next() // {done: true}

可迭代對象

可迭代對象必須實現一個 @@iterator 方法,也就是說在這個對象或者它的原型鏈上必須有一個方法名是 Symbol.iterator 的方法,當調用這個方法時它返回一個迭代器對象。

可迭代對象的表現形式為,可以使用 for...of 循環,解構賦值,拓展運算符(spread),yield* 這些語法來調用 Symbol.iterator 函數。也就是說這些語法糖在被調用時本質上都是在調用 Symbol.iterator 函數。

內置可迭代對象

String,Array,TypedArray,Map,Set,函數的arguments對象,NodeList對象都是內置的可迭代對象,他們的原型對象中都有一個 Symbol.iterator 方法。

// 可迭代對象 let iterable = [10, 20, 30] // 繼承自原型鏈 Symbol.iterator in iterable // true iterable.hasOwnProperty(Symbol.iterator) // falsefor(let value of iterable){console.log(value) } // 10 // 20 // 30

自定義可迭代對象

字面量對象 let o = {} 默認沒有 Symbol.iterator 方法,但是我們在對象上自定義一個 @@iterator 方法,此時字面量對象也可以使用 for...of循環,拓展運算符等等語法糖。

// 字面量對象默認是不可迭代對象 // 自定義對 var myIterable = {} myIterable[Symbol.iterator] = function(){return {arr: [10, 20, 30],next: function(){if(this.arr.length > 0){return {value: this.arr.shift(), done: false}}else{return {done: true}}}} } [...myIterable] // [10, 20, 30]

生成器

生成器 generator,在 Javascript 中生成器是一個函數(也可稱作生成器函數),它可以作為創建迭代器的工廠函數。生成器函數的返回值是一個迭代器對象,同時這個對象也是一個可迭代對象。

funtion* name(){ //statement } 這種聲明方式可以定義一個生成器函數。

生成器函數的語法規則是,調用一個生成器函數并不會馬上執行它里面的語句,而是返回一個這個生成器的 迭代器(iterator)對象。當這個迭代器的 next() 方法被首次(后續)調用時,其內的語句會執行到第一個(后續)出現yield的位置為止,yield 后緊跟迭代器要返回的值。或者如果用的是 yield*(多了個星號),則表示將執行權移交給另一個生成器函數(當前生成器暫停執行)。調用 next() 方法時,如果傳入了參數,那么這個參數會作為上一條執行的 yield 語句的返回值。

// 生成器函數 function* generator(i){yield i + 1var y = yield 'foo'yield y }var iterator = generator(10) // 此時生成器函數不執行,返回一個迭代器iterator.next() // {value: 11, done: false} iterator.next() // {value 'foo', done: false} iterator.next(10) // {value: 10, done: false},將10賦值給上一條 yield 'foo' 左側的值,即 y = 10,返回 y iterator.next() // {done: true}

既然 生成器函數 可以創建 迭代器對象,我們來試著將前面的例子用生成器函數的形式重寫試試看。

// 生成器函數 function* makeIterator(array) {for (let i = 0; i < array.length; i++) {yield array[i]} }// 迭代器對象,實現和上文一樣的功能 var iteratorByGen = makeIterator([10, 20, 30]) iteratorByGen.next() // {value: 10, done: false} iteratorByGen.next() // {value: 20, done: false} iteratorByGen.next() // {value: 30, done: false} iteratorByGen.next() // {done: true}

從上面的代碼我們可以看到,利用生成器函數來創建一個迭代器對象的方式相比于之前我們普通函數創建的方式更加簡潔,也更加清晰的表明調用生成器函數返回的是一個迭代器對象。除此之外還有什么區別呢。

上文已經提到,生成器函數返回的是一個 可迭代的迭代器對象,這是什么意思呢?看下代碼就明白了。

// 生成器函數創建的迭代器對象 Symbol.iterator in iteratorByGen // true [...iteratorByGen] // [10, 20, 30]// 普通函數創建的迭代器對象 Symbol.iterator in iterator // false [...iterator] // Uncaught TypeError: iterator is not iterable

綜上所述,我們可以確定的說 生成器函數是創建迭代器對象的語法糖 ,通過生成器函數我們可以用很簡潔清晰的語法創建一個可迭代的迭代器對象。

來源:https://segmentfault.com/a/1190000017529530

轉載于:https://www.cnblogs.com/qixidi/p/10185861.html

總結

以上是生活随笔為你收集整理的深入理解ES6之迭代器与生成器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。