成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ES6-迭代器(iterator)和生成器(generator)- 迭代器和生成器的高級用法

Edison / 691人閱讀

摘要:在生成器中使用語句生成器也是函數(shù),所以它也可以使用語句。只是由于生成器本身的特性,其內(nèi)部的的行為會和一般函數(shù)有些差別。

前面2篇系列文章講解了迭代器和生成器的最常用,最基礎(chǔ)的用法;這篇來討論迭代器和生成器的一些稍稍高級一點(diǎn)的用法:

1: 給迭代器的next()方法傳參
2: 從迭代器中拋出錯誤
3: 在生成器中使用return語句
4: 委托生成器(組合生成器或者生成器組合?)

1: 給迭代器的next()方法傳參
在前面2篇系列文章中我們使用的next()方法都是沒有傳參的,調(diào)用next()會依次返回迭代器里面的值。但是,實(shí)際上我們是可以給next()方法傳參數(shù)的,那在這種情況下我們會得到什么樣的結(jié)果呢?

function* createIterator() {
    let first = yield 1;
    console.log(`first: ${first}`);
    let second = yield first + 2;
    console.log(`second: ${second}`);
    let third = yield second + 3;
}
let iterator = createIterator();
console.log(iterator.next(0));
console.log(iterator.next(4));
console.log(iterator.next(5));
console.log(iterator.next());

我們得到下面的輸出結(jié)果:

{value: 1, done: false}
first: 4
{value: 6, done: false}
second: 5
{value: 8, done: false}
{value: undefined, done: true}

在第二次和第三次的next調(diào)用中我們分別傳入?yún)?shù)4和5,而4和5也分別被賦值給了變量first和second。當(dāng)我們執(zhí)行:
iterator.next(4)的時候,生成器內(nèi)部執(zhí)行的代碼實(shí)際上是:

let first = 4; yield 4 + 2; //所以我們得到 {value: 6, done: false}

iterator.next(5)的時候,生成器內(nèi)部執(zhí)行的代碼實(shí)際上是:

let second = 5; yield 5 + 3; //所以我們得到 {value: 8, done: false}

看下面一個圖或許能更直觀一些:

        以上截圖來自書 Understanding ECMAScript 6

但是上面的例子中,我們也看到一個有趣的現(xiàn)象,就是我們第一次調(diào)用next的時候,是傳了參數(shù)0的iterator.next(0),但是我們依然得到了結(jié)果{value: 1, done: false}。這是因為第一次調(diào)用next(),無論傳遞什么參數(shù)總是會被丟棄,所以給第一次調(diào)用的next()方法傳值是無意義的。
或許你看到這里也還不是完全明白了給next()傳參時,生成器內(nèi)部到底是怎樣工作。接下來我們再看一個例子,這一次我們在第3次調(diào)用next()的時候,不傳參數(shù),看會發(fā)生什么:

function* createIterator() {
    let first = yield 1;
    console.log(`first: ${first}`);
    let second = yield first + 2;
    console.log(`second: ${second}`);
    let third = yield second + 3;
}
let iterator = createIterator();
console.log(iterator.next(0));
console.log(iterator.next(4));
console.log(iterator.next());
console.log(iterator.next());

我們得到的輸出結(jié)果是:

{value: 1, done: false}
first: 4
{value: 6, done: false}
second: undefined
{value: NaN, done: false}
{value: undefined, done: true}

在第三次的next調(diào)用中,我們并沒有傳遞任何參數(shù),生成器內(nèi)部的執(zhí)行情況就是:

let second; yield undefined + 2; //所以我們得到結(jié)果{value: NaN, done: false}

其實(shí)從這里例子我們也可以看出,在生成器內(nèi)部,yield執(zhí)行的結(jié)果并不會被保存下來賦值給內(nèi)部的變量,例如這里我們在第三次沒有給next()傳遞參數(shù),那么second的值就是undefined,而不是第二次yield執(zhí)行結(jié)果的value 6。

2: 從迭代器中拋出錯誤
我們知道一般的函數(shù)的執(zhí)行結(jié)果有2種:

1: 返回一個值
2: 拋出一個錯誤

生成器函數(shù)作為一種特殊的函數(shù),但是它本身也是函數(shù),所以它也可以拋出錯誤。只是它拋出錯誤的時間與一般函數(shù)不同,看一下下面的代碼:

function* createIterator() {
    let first = yield 1;
    let second = yield first + 2;
    yield second + 3;
}
let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next(4)); //{value: 6, done: false}
console.log(iterator.throw(new Error("Boom"))); //Uncaught Error: Boom

在生成器內(nèi)部代碼執(zhí)行情況如下圖所示:

        以上截圖來自書 Understanding ECMAScript 6

當(dāng)我們拋出錯誤之后,代碼就停止了。let second語句并不會被執(zhí)行到。
但是生成器里面的throw()它會像yield一樣,也會返回一個結(jié)果。我們可以像一般函數(shù)一樣catch這個錯誤,并且之后的代碼依然可以得到執(zhí)行:

function* createIterator() {
    let first = yield 1;
    let second;
    try {
        second = yield first + 2;
    } catch (error) {
        second = 6;
    }
    yield second + 3;
}

let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next(4)); //{value: 6, done: false}
console.log(iterator.throw(new Error("Boom"))); //{value: 9, done: false}
console.log(iterator.next());//{value: undefined, done: true}

在這個例子中,我們catch了錯誤之后,給second賦值6,它后面的代碼yield second + 3;也依然可以得到執(zhí)行。
3: 在生成器中使用return語句
生成器也是函數(shù),所以它也可以使用return語句。只是由于生成器本身的特性,其內(nèi)部的return的行為會和一般函數(shù)有些差別。我們先來看兩個例子,就能從中窺探一二:
例1:

function* createIterator() {
    yield 1;
    return;
    yield 2;

}
let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next()); //{value: undefined, done: true}
console.log(iterator.next());//{value: undefined, done: true}

例2:

function* createIterator() {
    yield 1;
    return 2;
    yield 3;

}
let iterator = createIterator();
console.log(iterator.next()); //{value: 1, done: false}
console.log(iterator.next()); //{value: 2, done: true}
console.log(iterator.next()); //{value: undefined, done: true}

上面的例1只是使用了return語句,然后后面沒有跟任何值,例2代碼就return了一個數(shù)字,我們從調(diào)用next()的結(jié)果可以看到:

1: return語句會終止返回迭代器里面本可以再迭代的值,會把done設(shè)置為false
2: return語句如果指定一個值,那么此次結(jié)果的value會被賦為此值;如果沒有指定,那value為undefined

4: 委托生成器(組合生成器或者生成器組合?)
單個的生成器函數(shù)里,yield后面往往跟一些我們常用的數(shù)據(jù)類型;但是,我們也可以yield 一個生成器函數(shù),這樣的操作就叫委托生成器。先看一個代碼的例子:

function *createNumberIterator() {
    yield 1;
    yield 2;

}
function *createColorIterator() {
    yield "red";
    yield "yellow";

}
function *createCombinedIterator() {
    yield *createNumberIterator();
    yield *createColorIterator();

}
let combinedIterator = createCombinedIterator();
console.log(combinedIterator.next());//{value: 1, done: false}
console.log(combinedIterator.next());//{value: 2, done: false}
console.log(combinedIterator.next());//{value: "red", done: false}
console.log(combinedIterator.next());//{value: "yellow", done: false}
console.log(combinedIterator.next());//{value: undefined, done: true}

上面的這個示例,我們創(chuàng)建兩個不同的生成器函數(shù)createNumberIterator()和createColorIterator(),之后在createCombinedIterator()函數(shù)里通過yield語句調(diào)用前面的2個生成器函數(shù),這樣createCombinedIterator()就成了一個擁有以上2個生成器的迭代器的生成器,調(diào)用*createCombinedIterator()的next(),就跟一般的生成器的next()方法的行為一樣。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/110287.html

相關(guān)文章

  • ES6-迭代iterator生成generator) - 什么是迭代生成

    摘要:我個人認(rèn)為迭代器和生成器是新增的特性里面,非常重要的部分,充分地掌握和使用迭代器和生成器,是十分必要和重要的,所以我會寫關(guān)于二者的一系列文章。 我個人認(rèn)為迭代器和生成器是es6新增的特性里面,非常重要的部分,充分地掌握和使用迭代器和生成器,是十分必要和重要的,所以我會寫關(guān)于二者的一系列文章。話不多說,先來了解一下基本概念:一:什么是迭代器 1: 迭代器是一個對象 2: 迭代器有一個屬性...

    CollinPeng 評論0 收藏0
  • 【重溫基礎(chǔ)】13.迭代生成

    摘要:迭代器和生成器將迭代的概念直接帶入核心語言,并提供一種機(jī)制來自定義循環(huán)的行為。本文主要會介紹中新增的迭代器和生成器。屬性本身是函數(shù),是當(dāng)前數(shù)據(jù)結(jié)構(gòu)默認(rèn)的迭代器生成函數(shù)。 本文是 重溫基礎(chǔ) 系列文章的第十三篇。今日感受:每次自我年終總結(jié),都會有各種情緒和收獲。 系列目錄: 【復(fù)習(xí)資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎(chǔ)】1.語法和數(shù)據(jù)類型 【重溫基礎(chǔ)】2.流...

    ymyang 評論0 收藏0
  • ES6迭代與可迭代對象

    摘要:通過生成器創(chuàng)建的迭代器也是可迭代對象,因為生成器默認(rèn)會為屬性賦值。我們可以用來訪問對象的默認(rèn)迭代器,例如對于一個數(shù)組獲得了數(shù)組這個可迭代對象的默認(rèn)迭代器,并操作它遍歷了數(shù)組中的元素。 ES6 新的數(shù)組方法、集合、for-of 循環(huán)、展開運(yùn)算符(...)甚至異步編程都依賴于迭代器(Iterator )實(shí)現(xiàn)。本文會詳解 ES6 的迭代器與生成器,并進(jìn)一步挖掘可迭代對象的內(nèi)部原理與使用方法 ...

    terasum 評論0 收藏0
  • 《深入理解ES6》筆記——迭代Iterator生成Generator)(8)

    摘要:迭代器是一種特殊對象,每一個迭代器對象都有一個,該方法返回一個對象,包括和屬性。默認(rèn)情況下定義的對象是不可迭代的,但是可以通過創(chuàng)建迭代器。在迭代器中拋出錯誤不再執(zhí)行生成器返回語句生成器中添加表示退出操作。迭代器是一個對象。 迭代器(Iterator) ES5實(shí)現(xiàn)迭代器 迭代器是什么?遇到這種新的概念,莫慌張。 迭代器是一種特殊對象,每一個迭代器對象都有一個next(),該方法返回一個對...

    AndroidTraveler 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<