第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

JavaScript 無法迭代 Map 鍵或值

JavaScript 無法迭代 Map 鍵或值

忽然笑 2023-07-14 15:33:42
在某些情況下,嘗試迭代 JavaScript Map 鍵或值會失敗。該腳本根本不進入循環(huán)。function pushAndLog(array, values) {    array.push(...values);    for (const value of values) {        console.log(value);    }}const array = [];const map = new Map([["a", 1], ["b", 2]]);pushAndLog(array, map.keys());在此示例中,array已正確更新,但地圖鍵未記錄。
查看完整描述

2 回答

?
叮當貓咪

TA貢獻1776條經(jīng)驗 獲得超12個贊

原因

發(fā)生這種情況是因為Map.keys()和Map.values()方法返回Iterator而不是Iterable對象。

怎么修

避免重復使用迭代器

與 Iterable 相反,Iterator 是一個有狀態(tài)的對象。你不能重復使用它。特別是,如果將迭代器傳遞給函數(shù),則之后不能使用它 - 您應該創(chuàng)建一個新的迭代器。但這并不總是可能的。

使用可迭代對象

修復此代碼的最簡單方法是將集合而不是迭代器傳遞給函數(shù):

pushAndLog(array,?[...map.keys()]);

但這種解決方案通常不是最有效的,因為創(chuàng)建新集合會消耗內(nèi)存和 CPU 時間。有更好的解決方案。將以下實用程序添加到您的代碼中:

export function getIterableKeys<K, V>(map: Iterable<readonly [K, V]>): Iterable<K> {

? ? return {

? ? ? ? [Symbol.iterator]: function* () {

? ? ? ? ? ? for (const [key, _] of map) {

? ? ? ? ? ? ? ? yield key;

? ? ? ? ? ? }

? ? ? ? }

? ? };

}


export function getIterableValues<K, V>(map: Iterable<readonly [K, V]>): Iterable<V> {

? ? return {

? ? ? ? [Symbol.iterator]: function* () {

? ? ? ? ? ? for (const [_, value] of map) {

? ? ? ? ? ? ? ? yield value;

? ? ? ? ? ? }

? ? ? ? }

? ? };

}

使用它們代替原生 Map.keys() 和 Map.values() 方法:


pushAndLog(array, getIterableKeys(map));

它對于更大的地圖效果更好。

筆記:

  • 這些函數(shù)是用 TypeScript 編寫的。要將它們轉(zhuǎn)換為 JavaScript,只需從函數(shù)頭中刪除類型定義即可。

  • 這些函數(shù)被編寫為 ES6 模塊。要將它們轉(zhuǎn)換為純 JavaScript,只需刪除export關(guān)鍵字即可。

  • 嵌套函數(shù)是生成器函數(shù),即它們返回一個生成器,該生成器也可以用作迭代器。為了使用此代碼,請確保您的解釋器支持生成器或?qū)?TypeScript/Babel 轉(zhuǎn)譯器與regenerator-runtime庫結(jié)合使用。

一些想法

從 Map.keys() 和 Map.values() 方法返回 Iterator 對象是一個糟糕的設計決策,我們必須忍受并始終牢記在心。此類錯誤有時是意料之外的,并且很難跟蹤,因為迭代器在您嘗試重用它們之前效果很好。所以你必須保持警惕。

在其他成熟的編程語言中,此類方法巧妙地返回可迭代對象:

  • 在Java中,Map#keySet方法返回一個擴展了Iterable接口的Set;

  • 在.NET中,Dictionary.Keys屬性是一個實現(xiàn)IEnumerable接口的KeyCollection對象。

Java Iterable 和 .NET IEnumerable 都是可重用的,因此它們的用戶不會遇到相同的問題。這種方法更加安全。對我來說,一個問題是為什么相對年輕的 JavaScript 社區(qū)會發(fā)明自己的解決方案,而不是繼承現(xiàn)有成熟編程語言的最佳實踐。

盡管 JavaScript Iterator 的工作方式或多或少類似于 Iterable 對象(您可以在 for..of 循環(huán)、擴展運算符、集合構(gòu)造函數(shù)等中使用它),但它正式打破了可重用的 Iterable 類契約,而 Iterator 是不是。

TypeScript 定義假裝 Map.keys() 和 Map.values() 返回一個擴展 Iterable 接口的所謂 IterableIterator 對象,從而放大了這個問題,出于同樣的原因,這是錯誤的。



查看完整回答
反對 回復 2023-07-14
?
白衣非少年

TA貢獻1155條經(jīng)驗 獲得超0個贊

驚人的解決方案!


// 1.獲取Map的keys

export function getIterableKeys<K, V>(map: Iterable<readonly [K, V]>): Iterable<K> {

    return {

        [Symbol.iterator]: function* () {

            for (const [key, _] of map) {

                yield key;

            }

        }

    };

}


// 2.獲取key的values

export function getIterableValues<K, V>(map: Iterable<readonly [K, V]>): Iterable<V> {

    return {

        [Symbol.iterator]: function* () {

            for (const [_, value] of map) {

                yield value;

            }

        }

    };

}


查看完整回答
反對 回復 2023-07-14
  • 2 回答
  • 0 關(guān)注
  • 207 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學習伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號