欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

JavaScriptLazyevaluation中可迭代對象與迭代器是怎樣的

今天就跟大家聊聊有關(guān)JavaScript Lazy evaluation中可迭代對象與迭代器是怎樣的,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

成都創(chuàng)新互聯(lián)公司專注于常熟企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站定制開發(fā)。常熟網(wǎng)站建設(shè)公司,為常熟等地區(qū)提供建站服務(wù)。全流程按需求定制開發(fā),專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

Lazy evaluation

Lazy evaluation常被譯為“延遲計算”或“惰性計算”,指的是僅僅在真正需要執(zhí)行的時候才計算表達式的值。

與惰性求值相反的是及早求值(eager evaluation)及早求值,也被稱為貪婪求值(greedy  evaluation)或嚴(yán)格求值,是多數(shù)傳統(tǒng)編程語言的求值策略。

充分利用惰性求值的特性帶來的好處主要體現(xiàn)在以下兩個方面:

  • 避免不必要的計算,帶來性能上的提升。

  • 節(jié)省空間,使得無限循環(huán)的數(shù)據(jù)結(jié)構(gòu)成為可能。

迭代器

ES6  中的迭代器使惰性求值和創(chuàng)建用戶定義的數(shù)據(jù)序列成為可能。迭代是一種遍歷數(shù)據(jù)的機制。迭代器是用于遍歷數(shù)據(jù)結(jié)構(gòu)元素(稱為Iterable)的指針,用于產(chǎn)生值序列的指針。

迭代器是一個可以被迭代的對象。它抽象了數(shù)據(jù)容器,使其行為類似于可迭代對象。

迭代器在實例化時不計算每個項目的值,僅在請求時才生成下一個值。這非常有用,特別是對于大型數(shù)據(jù)集或無限個元素的序列。

可迭代對象

可迭代對象是希望其元素可被公眾訪問的數(shù)據(jù)結(jié)構(gòu)。JS 中的很多對象都是可迭代的,它們可能不是很好的察覺,但是如果仔細檢查,就會發(fā)現(xiàn)迭代的特征:

  • new Map([iterable])

  • new WeakMap([iterable])

  • new Set([iterable])

  • new WeakSet([iterable])

  • Promise.all([iterable])

  • Promise.race([iterable])

  • Array.from([iterable])

還有需要一個可迭代的對象,否則,它將拋出一個類型錯誤,例如:

  • for ... of

  • ... (展開操作符)const [a, b, ..] = iterable (解構(gòu)賦值)

  • yield* (生成器)

JavaScript中已有許多內(nèi)置的可迭代項:

String,Array,TypedArray,Map,Set。

迭代協(xié)議

迭代器和可迭對象遵循迭代協(xié)議。

協(xié)議是一組接口,并規(guī)定了如何使用它們。

迭代器遵循迭代器協(xié)議,可迭代遵循可迭代協(xié)議。

可迭代的協(xié)議

要使對象變得可迭代,它必須實現(xiàn)一個通過Symbol.iterator的迭代器方法,這個方法是迭代器的工廠。

使用 TypeScript,可迭代協(xié)議如下所示:

interface Iterable {   [Symbol.iterator]() : Iterator; }

Symbol.iterator]()是無參數(shù)函數(shù)。在可迭代對象上調(diào)用它,這意味著我們可以通過this來訪問可迭代對象,它可以是常規(guī)函數(shù)或生成器函數(shù)。

迭代器協(xié)議

迭代器協(xié)議定義了產(chǎn)生值序列的標(biāo)準(zhǔn)方法。

為了使對象成為迭代器,它必須實現(xiàn)next()方法。迭代器可以實現(xiàn)return()方法,我們將在本文后面討論這個問題。

使用 TypeScript,迭代器協(xié)議如下所示:

interface Iterator {     next() : IteratorResult;     return?(value?: any): IteratorResult; }

IteratorResult 的定義如下:

interface IteratorResult {     value?: any;     done: boolean; }
  • done通知消費者迭代器是否已經(jīng)被使用,false表示仍有值需要生成,true表示迭代器已經(jīng)結(jié)束。

  • value 可以是任何 JS 值,它是向消費者展示的值。

當(dāng)done為true時,可以省略value。

組合

迭代器和可以可迭代對象可以用下面這張圖來表示:

JavaScript Lazy evaluation中可迭代對象與迭代器是怎樣的

事例

基礎(chǔ)知識介紹完了,接著,我們來配合一些事例來加深我們的映像。

范圍迭代器

我們先從一個非常基本的迭代器開始,createRangeIterator迭代器。

我們手動調(diào)用it.next()以獲得下一個IteratorResult。最后一次調(diào)用返回{done:true},這意味著迭代器現(xiàn)在已被使用,不再產(chǎn)生任何值。

function createRangeIterator(from, to) {   let i = from;    return {     next() {       if (i <= to) {         return { value: i++, done: false };       } else {         return { done: true };       }     }   } }  const it = createRangeIterator(1, 3);  console.log(it.next()); console.log(it.next()); console.log(it.next()); console.log(it.next());

可迭代范圍迭代器

在本文的前面,我已經(jīng)提到 JS 中的某些語句需要一個可迭代的對象。因此,我們前面的示例在與for ... of循環(huán)一起使用時將不起作用。

但是創(chuàng)建符合迭代器和可迭代協(xié)議的對象非常容易。

JavaScript Lazy evaluation中可迭代對象與迭代器是怎樣的

function createRangeIterator (from, to) {   let i = from    return {     [Symbol.iterator] () {       return this     },     next() {       if (i <= to) {         return { value: i++, done: false }       } else {         return { done: true }       }     }   } }  const it = createRangeIterator(1, 3)  for (const i of it) {   console.log(i) }

無限序列迭代器

迭代器可以表示無限制大小的序列,因為它們僅在需要時才計算值。

注意不要在無限迭代器上使用擴展運算符(...),JS 將嘗試消費迭代器,由于迭代器是無限的,因此它將永遠不會結(jié)束。所以你的應(yīng)用程序?qū)⒈罎ⅲ驗閮?nèi)存已被耗盡  ??

同樣,for ... of 循環(huán)也是一樣的情況,所以要確保能退出循環(huán):

function createEvenNumbersIterator () {   let value = 0    return {     [Symbol.iterator] () {       return this     },     next () {       value += 2       return { value, done: false}     }   } }  const it = createEvenNumbersIterator()  const [a, b, c] = it console.log({a, b, c})  const [x, y, z] = it console.log({ x, y, z })  for (const even of it) {   console.log(even)   if (even > 20) {     break   } }

JavaScript Lazy evaluation中可迭代對象與迭代器是怎樣的

關(guān)閉迭代器

前面我們提到過,迭代器可以有選擇地使用return()方法。當(dāng)?shù)髦钡阶詈蠖紱]有迭代時使用此方法,并讓迭代器進行清理。

for ... of循環(huán)可以通過以下方式更早地終止迭代:

  • break

  • continue

  • throw

  • return

function createCloseableIterator () {   let idx = 0   const data = ['a', 'b', 'c', 'd', 'e']    function cleanup() {     console.log('Performing cleanup')   }   return {     [Symbol.iterator]() { return this },     next () {       if (idx <= data.length - 1) {         return { value: data[idx++], done: false }       } else {         cleanup()         return { done: true }       }     },     return () {       cleanup()       return { done: true }     }   } }  const it = createCloseableIterator()  for (const value of it) {   console.log(value)   if (value === 'c') {     break   } }  console.log('\n----------\n')  const _it = createCloseableIterator(); for (const value of _it) {   console.log(value); }

JavaScript Lazy evaluation中可迭代對象與迭代器是怎樣的

  • 如果知道迭代器已經(jīng)結(jié)束,則手動調(diào)用cleanup()函數(shù)。

  • 如果突然完成,則return()起作用并為我們進行清理。

額外的內(nèi)容

如果你已經(jīng)做到了這一點,我們來看看一些額外的內(nèi)容。

組合器

組合器是將現(xiàn)有可迭代對象組合在一起以創(chuàng)建新可迭代對象的函數(shù)。

因此,我們能夠創(chuàng)建許多實用函數(shù)。那map或者filter呢?看看下面的代碼,花一分鐘時間來理解它。

function createEvenNumbersIterator() {   let value = 0;    return {     [Symbol.iterator]() {       return this;     },     next() {       value += 2;       return { value, done: false };     }   } }  function map(fn, iterable) {   const iter = iterable[Symbol.iterator]();    return {     [Symbol.iterator]() {       return this;     },     next() {       const n = iter.next();       if (!n.done) {         return { value: fn(n.value), done: false };       } else {         return { done: true };       }     }   } }  function filter(fn, iterable) {   const iter = iterable[Symbol.iterator]();    return {     [Symbol.iterator]() {       return this;     },     next() {       const n = iter.next();       if (!n.done) {         if (fn(n.value)) {           return { value: n.value, done: false };         } else {           return this.next();         }       } else {         return { done: true };       }     }   } }  function take(n, iterable) {   const iter = iterable[Symbol.iterator]();    return {     [Symbol.iterator]() {       return this;     },     next() {       if (n > 0) {         n--;         return iter.next();       } else {         return { done: true };       }     }   } }  function cycle(iterable) {   const iter = iterable[Symbol.iterator]();   const saved = [];   let idx = 0;      return {     [Symbol.iterator]() {       return this;     },     next() {       const n = iter.next();       if (!n.done) {         saved[idx++] = n.value;         return { value: n.value, done: false };       } else {         return { value: saved[idx++ % saved.length], done: false };       }     }   } }  function collect(iterable) {   // consumes the iterator   return Array.from(iterable); }  const evenNumbersIterator = createEvenNumbersIterator(); const result = collect(                 // 7. and collect the result   filter(                               // ?? 6. keep only values higher than 1     val => val > 1, map(                // ?? 5. divide obtained values by 2       val => val / 2, take(             // ?? 4. take only six of them         6, cycle(                       // ?? 3. make an infinite cycling sequence of them           take(                         // ?? 2. take just three of them             3, evenNumbersIterator      // ?? 1. infinite sequence of even numbers           )         )       )     )   ) );  console.log(result);

看完上述內(nèi)容,你們對JavaScript Lazy evaluation中可迭代對象與迭代器是怎樣的有進一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

名稱欄目:JavaScriptLazyevaluation中可迭代對象與迭代器是怎樣的
鏈接地址:http://www.chinadenli.net/article32/iphosc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站網(wǎng)站設(shè)計公司服務(wù)器托管外貿(mào)建站App開發(fā)小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)