Iterator 與Generator

by vivid 28. 十二月 2016 12:29

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號: N161217802
出刊日期: 2016/12/28

本文將介紹ECMAScript 2015的Iterator 與Generator語法。

 

Iterator 與Generator

Iterator

ECMAScript 2015為JavaScript新增Iterator,也新增了for .. of迴圈語法,以便於從陣列或集合中,快速的取出包含在其中的項目,不似for迴圈需要維護一個變數當索引,來追蹤其中的項目。

Iterator是一個物件,提供列舉的功能,列舉是指能夠從一堆資料中一次取出一個的能力。所有的Iterator都有一個next()方法,回傳一個result物件,result物件有兩個屬性:value與done。Iterator內部包含一個指標,指向集合中的值,每當叫用next()方法,就可從value屬性取得下一個值;而done屬性是一個布林值,當沒有東西可回傳時,done的值就會是true,否則則為false。

預設以下的物件都內建列舉功能:

  • Array(陣列)
  • String(字串)
  • Map
  • Set

有支援列舉功能的物件,稱Iterable。

 

Generator

Generator是一個函式(function),回傳一個Iterator,Generator呼叫時就跟一般的函式呼叫語法一樣。Generator function的名稱以「*」號開始,再加上文字的名稱,「*」號與文字名稱之間允許有空白,或不含空白,例如「*getIterator」或「* getIterator」(含一個空白)都是合法的名稱。

參考以下範例程式碼, 定義一個名為「*getIterator」的Generator函式,在其中使用了yield關鍵字,指定在next()方法呼叫時,要回傳的值。每當呼叫next()方法一次,就按yield程式中程式的順序,回傳100、200、300、400、500的值,每次叫用next()方法,你可以檢視result物件的value與done屬性,value屬性取得值,而done屬性則可用來判斷Iterator中是否還含有值。此範例由於iterator中只包含5個數值,而程式中叫用next()方法六次,叫用第六次next()方法印出的值就會是「undefined」:

function *getIterator() {
yield 100;
yield 200;
yield 300;
yield 400;
yield 500;
  }


  let ite = getIterator();

  console.log( ite.next().value );     // 100
  console.log( ite.next().value );     // 200
  console.log( ite.next().value );     // 300
  console.log( ite.next().value );     // 400
 
  let n =ite.next();
  console.log( n.done );      // false
  console.log( n.value ); // 500

   n =ite.next();
  console.log( n.done );     // true
  console.log( n.value );     // undefined


 

yield關鍵字只可以在Geneator函式中使用,在其它地方使用時,則會產生語法錯誤。每次執行到Geneator函式中的yield陳述式,Geneator函式就會停止執行,以上述程式碼為例,當執行到「yield 100;」這行,Geneator函式就會停止執行,直到下一次next()方法被叫用時,才繼續執行Geneator函式中下一行程式碼「yield 200;」。

你也可使用函式運算式(Function Expressions)語法來定義Generator,只需要將「*」號放在function關鍵字與「(」號之間,參考以下範例程式碼 :

let getIterator=  function *() {
  yield 100;
  yield 200;
  yield 300;
  yield 400;
  yield 500;
}

let ite = getIterator();

console.log( ite.next().value );     // 100
console.log( ite.next().value );     // 200
console.log( ite.next().value );     // 300
console.log( ite.next().value );     // 400
console.log( ite.next().value );     // 500


 

在物件宣告Generator

因為Generator Function就是一個函式(function),因此你可以在物件宣告Generator函式,以下是使用Object Literal Notation語法搭配EMCAScript 5語法來宣告Generator的範例程式,在nums物件getIterator()方法 function關鍵字之後加上「*」號,function關鍵字與「*」號之間可以有空白,沒有空白也不會出錯:

let nums = {
  getIterator : function *() {
    yield 100;
    yield 200;
    yield 300;
    yield 400;
    yield 500;
  }      
};

var ite = nums.getIterator();
console.log( ite.next().value );     // 100
console.log( ite.next().value );     // 200
console.log( ite.next().value );     // 300
console.log( ite.next().value );     // 400
console.log( ite.next().value );     // 500


以下是使用Object Literal Notation語法搭配EMCAScript 2015方法的語法來宣告Generator的範例程式,在nums物件getIterator方法名稱之前加上「*」號,「getIterator」與「*」號之間可以有空白,也可以沒有空白:

let nums = {
  *getIterator(){
    yield 100;
    yield 200;
    yield 300;
    yield 400;
    yield 500;
  }
};

var ite = nums.getIterator();
console.log( ite.next().value );     // 100
console.log( ite.next().value );     // 200
console.log( ite.next().value );     // 300
console.log( ite.next().value );     // 400
console.log( ite.next().value );     // 500

 

使用for ..of迴圈取值

只要物件具備Iterator,就可以使用for ..of迴圈語法,一個個取出物件其中的值,在JavaScript之中所有的集合、陣列、Set與Map都可以使用for ..of迴圈語法。若在不具備Iterator的物件使用for ..of迴圈語法,執行時將會產生例外錯誤。

for ..of迴圈會在每一輪程式的最後,自動叫用Iterator的next()方法,取出Iterator下一個值,直到取出所有值為止,參考以下範例程式碼,使用for ..of迴圈將陣列中所有的字串一一印出:

let employees = ["Mary", "Candy", "Lili", "Jane"];

for (let emp of employees) {
   console.log(emp);
}

 

這個範例程式碼執行的結果參考如下:

Mary
Candy
Lili
Jane

ECMAScript 2015內建的Iterator

ECMAScript 2015定義三種Iterator來取回集合中的內容:

  • entries:回傳可讀取 key/value配對值的Iterator。
  • values:回傳集合的iterator。
  • keys:回傳值有包含key的集合。

Entries() Iterator

entries() Iterator在每次叫用next()方法時,回傳一個包含兩個項目的陣列,第一個項目根據包含Iterator的物件而略有不同,若是陣列,則第一個項目為數值索引;第二個項目為陣列值。entries() Iterator是使用for..of搭配Map物件時的預設Iterator。參考以下範例程式碼 :

let employees = ["Mary", "Candy", "Lili", "Jane"];

for (let entry of employees.entries() )

{

console.log( entry[0] + "," + entry[1] );

}

這個範例程式碼執行的結果參考如下:

0 , Mary
1 , Candy
2 , Lili
3 , Jane

若是Map物件,叫用next()方法回傳的陣列,陣列中第一個項目為key;第二個項目為value,參考以下範例程式碼 :

let map = new Map();
map.set( "id", 1 );
map.set( "name", "mary" );

for (let entry of map.entries() )
{
  console.log(  entry[0] + " , " + entry[1] );
}

 

這個範例程式碼執行的結果參考如下:

id , 1
name  ,  mary

若是Set物件,叫用next()方法回傳的陣列,則陣列中第一個項目和第二個項目都是value,參考以下範例程式碼 :

let set = new Set( [10, 20, 30] );

for (let entry of set.entries() )
{
  console.log( entry[0] + " , " + entry[1] );
}

這個範例程式碼執行的結果參考如下:

10 , 10
20 , 20
30 , 30

values() Iterator

values() Iterator回傳集合中的值,它是使用for..of迴圈搭配陣列、Set物件時的預設Iterator。參考以下範例程式碼,使用values() Iterator來取出Map物件中項目的值:

let map = new Map();
map.set( "id", 1 );
map.set( "name", "mary" );

for ( let value of map.values() )
{
  console.log( value );
}


這個範例程式碼執行的結果參考如下:

1
mary

若是Set物件,參考以下範例程式碼,使用values() Iterator來取出Set物件中項目的值:

let set = new Set( [10, 20, 30] );

for ( let value of set.values() )
{
  console.log( value );
}


這個範例程式碼執行的結果參考如下:

10
20
30

 

keys() Iterator

keys() Iterator回傳key,對於陣列而言,回傳的是數值索引,參考以下範例程式碼 :

let employees = ["Mary", "Candy", "Lili", "Jane"];
 
for ( let key of employees.keys() )
{
  console.log( key );
}


這個範例程式碼執行結果參考如下:

0
1
2
3

若是Map物件,keys() Iterator將回傳key,參考以下範例程式碼 :

let map = new Map();
map.set( "id", 1 );
map.set( "name", "mary" );

for ( let key of map.keys() )
{
  console.log( key );
}


 

這個範例程式碼執行結果參考如下:

id
name

若是Set物件,keys() Iterator回傳的key和value都相同,參考以下範例程式碼 :

let set = new Set( [10, 20, 30] );

for ( let key of set.keys() )
{
  console.log( key );
}
console.log( "" );
for ( let value of set.values() )
{
  console.log( value );
}


這個範例程式碼執行結果參考如下:

10
20
30

Tags:

.NET Magazine國際中文電子雜誌 | JavaScript | 許薰尹Vivid Hsu

評論 (64) -

cours de theatre
cours de theatre United States
2017/10/1 上午 02:16:16 #

Wow, great blog. Really Great.

回覆

dic phoenix
dic phoenix United States
2017/10/6 下午 11:33:14 #

Major thanks for the article. Great.

回覆

Buy illegal backlinks
Buy illegal backlinks United States
2017/10/9 下午 01:28:01 #

Im grateful for the post.Really looking forward to read more. Really Great.

回覆

sklep z lekami na potencje
sklep z lekami na potencje United States
2017/10/9 下午 03:05:53 #

Muchos Gracias for your blog article.Really looking forward to read more. Much obliged.

回覆

Osimi seaview
Osimi seaview United States
2017/10/9 下午 05:22:33 #

This is one awesome article post.Much thanks again. Want more.

回覆

solarmovie
solarmovie United States
2017/10/10 下午 07:10:53 #

Looking forward to reading more. Great blog article.Thanks Again. Awesome.

回覆

Sterling Businesses Ltd
Sterling Businesses Ltd United States
2017/10/10 下午 09:17:27 #

I think this is a real great post.Thanks Again. Fantastic.

回覆

pirater un compte facebook
pirater un compte facebook United States
2017/10/10 下午 11:36:09 #

Muchos Gracias for your blog.Really thank you! Great.

回覆

Buy illegal backlinks
Buy illegal backlinks United States
2017/10/12 下午 08:00:40 #

Thank you for your blog. Cool.

回覆

find here
find here United States
2017/10/14 下午 03:16:04 #

I really like and appreciate your post.Much thanks again. Will read on...

回覆

dragon city hack apk download
dragon city hack apk download United States
2017/10/15 下午 02:43:40 #

I think this is a real great article post.Really thank you! Really Great.

回覆

omega xl
omega xl United States
2017/10/15 下午 07:25:40 #

Thanks again for the blog post.Much thanks again. Really Cool.

回覆

see this here
see this here United States
2017/10/17 下午 02:01:10 #

Say, you got a nice article post.Thanks Again. Much obliged.

回覆

sletrokor
sletrokor United States
2017/10/17 下午 07:33:31 #

I truly appreciate this blog post. Really Great.

回覆

officetel
officetel United States
2017/10/19 上午 04:56:07 #

Hey, thanks for the post.Really thank you!

回覆

sex pill
sex pill United States
2017/10/19 上午 06:37:56 #

I appreciate you sharing this blog.Really thank you! Want more.

回覆

Website
Website United States
2017/10/19 下午 05:26:51 #

Appreciate you sharing, great post.Much thanks again. Will read on...

回覆

pure slim 1000 review
pure slim 1000 review United States
2017/10/20 上午 02:57:24 #

Appreciate you sharing, great article.Really looking forward to read more. Cool.

回覆

vung tau melody
vung tau melody United States
2017/10/21 上午 02:40:02 #

I loved your article.Thanks Again. Want more.

回覆

carte grise en ligne
carte grise en ligne United States
2017/10/21 上午 06:18:05 #

Really informative blog.Really looking forward to read more. Great.

回覆

Turbotax customer service
Turbotax customer service United States
2017/10/24 上午 09:47:28 #

I value the post.Much thanks again. Much obliged.

回覆

vung tau melody
vung tau melody United States
2017/10/28 上午 09:30:04 #

I loved your article post.Really thank you! Want more.

回覆

EZ Battery Reconditioning Scam
EZ Battery Reconditioning Scam United States
2017/10/30 上午 08:22:42 #

I value the blog.Really thank you! Want more.

回覆

lepszy plock
lepszy plock United States
2017/10/30 下午 04:08:04 #

Really informative article. Cool.

回覆

dweebs
dweebs United States
2017/11/1 上午 08:37:01 #

Thank you ever so for you article.Really looking forward to read more. Want more.

回覆

phenocal
phenocal United States
2017/11/1 下午 04:02:10 #

I think this is a real great blog.Thanks Again. Want more.

回覆

phentaslim review
phentaslim review United States
2017/11/3 下午 01:41:59 #

Im grateful for the post.Thanks Again. Awesome.

回覆

natural remedies for back pain
natural remedies for back pain United States
2017/11/15 上午 05:15:33 #

Major thanks for the blog article.Thanks Again. Really Cool.

回覆

criminel avocat
criminel avocat United States
2017/11/16 下午 03:53:57 #

Say, you got a nice blog.Thanks Again. Great.

回覆

https://penzu.com/p/f57618e9
https://penzu.com/p/f57618e9 United States
2017/11/17 下午 02:22:30 #

Very good blog article. Awesome.

回覆

hack into whatsapp
hack into whatsapp United States
2017/11/22 上午 12:21:16 #

Say, you got a nice blog.Really looking forward to read more. Really Great.

回覆

Chad Boonswang and Jeffrey Goodman
Chad Boonswang and Jeffrey Goodman United States
2017/11/26 下午 03:26:31 #

Hey, thanks for the article post.Thanks Again. Awesome.

回覆

Chad Boonswang SEO
Chad Boonswang SEO United States
2017/11/26 下午 09:24:10 #

Appreciate you sharing, great blog.Really thank you! Much obliged.

回覆

car wrecker scammer
car wrecker scammer United States
2017/11/29 下午 01:49:34 #

Very neat blog. Much obliged.

回覆

Opal Skyview
Opal Skyview United States
2017/11/29 下午 08:19:13 #

Im grateful for the post.Really looking forward to read more. Much obliged.

回覆

primary trade lines
primary trade lines United States
2017/11/30 下午 10:15:27 #

Muchos Gracias for your post. Fantastic.

回覆

porno
porno United States
2017/12/1 下午 01:57:37 #

Im obliged for the blog post. Awesome.

回覆

Build Business Credit
Build Business Credit United States
2017/12/3 上午 02:13:07 #

Hey, thanks for the blog post. Keep writing.

回覆

mobile hentai
mobile hentai United States
2017/12/5 上午 07:01:44 #

Really appreciate you sharing this post.Really thank you! Will read on...

回覆

Muchos Gracias for your article.Really thank you!

回覆

michel law
michel law United States
2017/12/10 下午 03:49:09 #

Muchos Gracias for your blog article.

回覆

Sterling Lagasse
Sterling Lagasse United States
2017/12/14 上午 06:50:38 #

Really appreciate you sharing this article.Much thanks again. Really Great.

回覆

find out here
find out here United States
2017/12/14 下午 01:40:33 #

I appreciate you sharing this blog post.Much thanks again. Fantastic.

回覆

Christmas Songs
Christmas Songs United States
2017/12/14 下午 08:07:19 #

Appreciate you sharing, great article post.Really thank you! Keep writing.

回覆

canon drivers
canon drivers United States
2017/12/16 下午 03:23:13 #

Im grateful for the article post.Really thank you! Keep writing.

回覆

I appreciate you sharing this article.Really looking forward to read more. Awesome.

回覆

Growth
Growth United States
2017/12/17 下午 03:06:16 #

Major thankies for the blog post.Really thank you! Will read on...

回覆

work online
work online United States
2017/12/20 下午 04:14:15 #

I really enjoy the blog.Really thank you!

回覆

driver canon
driver canon United States
2017/12/23 上午 07:45:24 #

I truly appreciate this blog.Thanks Again. Awesome.

回覆

hp driver
hp driver United States
2017/12/25 下午 07:44:47 #

I loved your article.Thanks Again. Really Great.

回覆

I really liked your article post.Really thank you! Fantastic.

回覆

Wow, great article.Really looking forward to read more. Will read on...

回覆

SOCCER HIGHLIGHTS
SOCCER HIGHLIGHTS United States
2017/12/26 下午 03:00:26 #

Thanks-a-mundo for the blog post.Really thank you! Really Great.

回覆

canon drivers
canon drivers United States
2017/12/27 下午 02:52:45 #

A big thank you for your post.Really thank you! Will read on...

回覆

hp drivers
hp drivers United States
2018/1/2 上午 05:38:07 #

Looking forward to reading more. Great article post.Much thanks again.

回覆

about his
about his United States
2018/1/2 下午 01:35:08 #

Great post.Much thanks again. Keep writing.

回覆

I really liked your post. Really Great.

回覆

canon drivers
canon drivers United States
2018/1/3 上午 04:53:50 #

Very informative blog article.Really looking forward to read more. Will read on...

回覆

online slots real money usa
online slots real money usa United States
2018/1/4 下午 03:25:45 #

Thanks a lot for the post.Really thank you!

回覆

hp printer driver
hp printer driver United States
2018/1/5 下午 03:39:22 #

Very neat post.Much thanks again.

回覆

FBA
FBA United States
2018/1/6 上午 07:43:43 #

Very informative blog post.Thanks Again. Keep writing.

回覆

web hosting
web hosting United States
2018/1/10 上午 07:03:51 #

Hey, thanks for the article post.Much thanks again. Really Cool.

回覆

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List