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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

生成器和迭代器

發布時間:2025/4/14 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 生成器和迭代器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Generator生成器函數

Generator函數是ES2015提出的異步的解決方案,與普通的函數有很大的不同;

生成器提供了一種【中斷機制】,使得子程序可以暫時返回,等在之后的某個時刻,繼續回來運行。

特點:

(1)generator函數與普通函數不同,普通函數一旦調用就會執行完,但是generator函數中間可以暫停,執行一會歇一會。

(2)在function關鍵字后面跟一個(*)號;

(3)在函數體內部使用yield表達式作為一個狀態,實現暫停;

(4)generator函數執行并不會有什么效果,而是返回一個迭代器對象,之后調用迭代器的next方法會返回一個值對象。

舉例說明:

?

function *go(a){console.log(1);//yield語句只是標識符,并沒有返回值//yield左邊等于next()傳來的參數值,沒傳參則為undefined,yield右邊是next()的返回值let b=yield a;console.log(2);let c=yield b;console.log(3);return c;}let iterator=go('aaa');let r1=iterator.next();//第一次next()不用傳參console.log(r1);// 1 {value: "aaa", done: false} let r2=iterator.next('bbb');console.log(r2);//2 {value: "bbb", done: false} let r3=iterator.next();console.log(r3);//3 {value: undefined, done: true} done屬性值代表當前迭代是否完成。//例2 function *gen(x){var y=2*(yield (x+1));var z=yield (y/3);return x+y+z; } var t=gen(5); console.log(t.next());//{value: 6, done: false} console.log(t.next(12));//{value: 8, done: false} console.log(t.next(13));//{value: 42, done: true} //解析:yield (x+1)表達式將傳遞值6到外部,在第二次調用next(12)的時候,傳遞12到generator函數內部作為yield(x+1)表達式的值,因此y被賦值12*12=24.接下來,下一條yield(y/3) 將向外傳值值8.第三次調用next(13)傳遞13到generator函數內部給yield(y/3),所以z的值為13

?

?

在生成器中的return值:便利返回對象的done值為true時迭代即結束,不會對該value處理。

function *createIterator() {yield 1;return 42;yield 2; } let iterator1 = createIterator(); console.log(...iterator); // 1

?

async是Generator函數的語法糖。async的實現原理就是將Generator函數和自動執行器包裝在一個函數里。

?相比于generator,Async函數有以下幾點改進:

(1)內置執行器。generator函數的執行必須依賴執行器,而async函數自帶執行器,調用的方式和普通函數的調用一樣。

(2)返回值是promise對象。比起generator函數返回的iterator對象更加方便,可以直接使用then()方法調用。

?

二、Iterator迭代器

迭代器是一種特殊的對象,它具有一些專門為迭代過程設計的接口,所有的迭代器對象都有一個next()方法,每次調用都返回一個結果對象。該結果對象有兩個屬性:value(表示下一個將要返回的值)和done(布爾值,表示迭代過程是否結束)

?

手動實現一個簡單的迭代器

測試數據:

?

?

三、可迭代對象

1、可迭代對象具有Symbol.iterator屬性,是一種與迭代器密切相關的對象。

  在ES6中所有集合對象(Array、Set結構和Map結構)和String都是可迭代對象,這些對象都有默認的迭代器。

  ES6中新加入的特性for of循環需要用到可迭代對象這些功能。

  for-of循環每執行一次都會調用可迭代對象的next()方法,并將迭代器返回的結果對象的value屬性存儲在一個變量中,循環將持續執行這一過程直到返回對象的done屬性值為true。

  通過生成器創建的迭代器也是可迭代對象,因為生成器默認會為Symbol.iterator屬性賦值。

?

2、判斷一個數據是否具有可迭代能力,只有當數據具有Symbol.iterator屬性的時候才可以使用for-of進行迭代。

? ? ? ??

?

3、默認迭代器

ES6為很多內置對象提供了默認的迭代器,只有當內建的迭代器不能滿足需求時才自己創建迭代器。

S6的三個集合對象:Set、Map、Array都有默認的迭代器,常用的如values()方法、entries()方法、keys()方法都返回一個迭代器。其值區別如下:

  • entries():多個鍵值對
  • values():集合的值
  • keys():集合的鍵
var obj={a:1,b:2,c:3 } for(let item of obj){console.log(item)//Uncaught TypeError: obj is not iterable } for(let item of Object.keys(obj)){console.log(item)//a,b,c } for(let item of Object.values(obj)){console.log(item)//1,2,3 }

?

我們可以通過Symbol.iterator屬性來訪問可迭代對象的默認迭代器。例如對一個數組:

?

?

思考:

1、既然數組等具有可迭代能力,但是為什么我們直接用arr.next()或報錯?

是因為可迭代對象不代表是一個迭代器,只有迭代器才具有next()方法。所以具有可迭代能力的對象,如果想要使用next()方法,必須先轉換為迭代器。

可迭代對象不一定是迭代器,但是迭代器一定是可迭代對象。

?

?

?

co模塊?

用于generator函數的自動執行。是我們可以不用編寫generator函數的執行器。

co模塊其實是將兩種自動執行器(thunk函數和promise對象)包裝成一個模塊,然后返回的是promise對象。

轉載于:https://www.cnblogs.com/xiaoan0705/p/11404861.html

總結

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

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