」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 Symbol.iterator 控制循環

使用 Symbol.iterator 控制循環

發佈於2024-11-18
瀏覽:281

Take control of loops with Symbol.iterator

您是否曾经使用过 Object.entries 并想知道它是如何工作的?比你想象的要简单得多!

这是一个基本实现:

function objectEntries(obj) {
  const entries = [];

  for (const key in obj) {
    if (Object.hasOwn(obj, key)) {
      entries.push([key, obj[key]]);
    }
  }

  return entries;
}

然而,这段代码还不够好——如果对象很大怎么办?在执行该函数的整个过程中,基于数组的方法的性能必须存储在内存中。如果你再次使用它呢?它必须同样构建并在内存中保存一个新数组。在现实世界中,这可能会导致严重的性能问题,并且在某些时候我们需要适应性能。然而,有一个优雅的解决方案可以解决所有这些问题,其中 Symbol.iterator 来拯救!

这是更新的片段:

function objectEntries(obj) {
  return {
    [Symbol.iterator]() {
      const keys = Object.keys(obj);
      let index = 0;

      return {
        next() {
          if (index 



为什么使用Symbol.iterator进行迭代?

在我们的初始实现中,objectEntries 函数在内存中构建所有条目([key, value] 对)的数组,如果对象具有大量属性,这可能会出现问题。将所有条目存储在数组中意味着我们必须提前为每一对分配内存。这种方法对于较小的对象来说相当不错,但随着对象大小的增加,它很快就会变得低效并且速度很慢。

在更新的代码中,我们在保存迭代逻辑的对象上定义[Symbol.iterator]。让我们一步步分解:

  • 初始化Keys:Object.keys(obj)从对象obj中获取键数组。这个键列表使我们能够准确地知道我们需要访问哪些属性,而无需存储每个条目。
  • 使用索引指针:变量索引跟踪我们在键数组中的当前位置。这是我们在循环中唯一的状态。
  • 定义 next 方法:next() 函数使用索引来检索当前键并递增它。它返回每个 [key, obj[key]] 对作为值,并在我们迭代所有键时设置 did: true。
  • 通过这样做,我们使 objectEntries 能够与任何 for...of 循环兼容,而无需预先创建整个条目数组的内存成本。

将 Symbol.iterator 应用于自定义循环

让我们更深入地了解这些方法如何提供对循环行为的更多控制。提供的每个示例都演示了与数组数据交互的独特方式,为您的代码增加了很大的灵活性。我们将探讨每种方法的含义以及如何在不同场景中利用它们。

在这些示例中,我将使用示例方法扩展数组原型(有关原型的更多信息),以使我的代码更易于阅读。让我们直接进入吧!

例如,此反向迭代器方法在聊天应用程序之类的应用程序中很有用,您可能希望首先显示最新的消息。聊天应用程序因拥有大量数据(在本例中为消息)而臭名昭著。使用reverseIterator,您可以迭代消息列表并按所需顺序显示它们,而无需创建新的反向数组。

Array.prototype.reverseIterator = function() {
  let index = this.length - 1;
  return {
    [Symbol.iterator]: () => ({
      next: () => {
        if (index >= 0) {
          return { value: this[index--], done: false };
        }
        return { done: true };
      }
    })
  };
};

const numbers = [1, 2, 3, 4, 5];
for (const num of numbers.reverseIterator()) {
  console.log(num); // 5, 4, 3, 2, 1
}

这种独特的方法使您能够迭代数组,同时确保仅生成唯一值。这对于动态消除重复项非常有用,无需提前过滤并使用更多内存。

Array.prototype.unique = function() {
  const seen = new Set();
  return {
    [Symbol.iterator]: () => ({
      next: () => {
        for (let i = 0; i 



下面的 chunk 方法在处理大型数据集时非常有用,您可以将它们分成较小的块来处理,以减少内存使用并提高性能。假设您正在从 CSV 文件之类的文件导入数据,您可以在更具可扩展性的段中读取和处理它。此外,在 Web 用户界面中,分块可用于分页,允许您在每页显示特定数量的项目或帮助您更好地管理无限加载器。

Array.prototype.chunk = function(size) {
  let index = 0;
  return {
    [Symbol.iterator]: () => ({
      next: () => {
        if (index 



结论

在本文中,我们探讨了 Symbol.iterator 如何自定义逻辑并提高循环效率。通过在 Array.prototype(或任何其他可迭代的效果)上实现自定义可迭代方法,我们可以有效地管理内存使用并控制循环的运行方式。

objectEntries 的初始示例演示了基于数组的方法在处理大型对象时如何导致性能问题。然而,通过使用 SYmbol.iterator,我们创建了一个有效的解决方案,允许我们迭代对象条目,而无需不必要的内存分配开销。

我们还研究了几个实际示例,说明扩展 Array.prototype 如何促进开发人员日常处理的各种现实场景。

有了这些强大的工具,您可以更好地解决 JavaScript 中复杂的数据处理场景,对应用程序的性能影响几乎为零。

版本聲明 本文轉載於:https://dev.to/vanyaxk/take-control-of-loops-with-symboliterator-4lon?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • Java數組中元素位置查找技巧
    Java數組中元素位置查找技巧
    在Java數組中檢索元素的位置 利用Java的反射API將數組轉換為列表中,允許您使用indexof方法。 (primitives)(鏈接到Mishax的解決方案) 用於排序陣列的數組此方法此方法返回元素的索引,如果發現了元素的索引,或一個負值,指示應放置元素的插入點。
    程式設計 發佈於2025-06-07
  • 在C#中如何高效重複字符串字符用於縮進?
    在C#中如何高效重複字符串字符用於縮進?
    在基於項目的深度下固定字符串時,重複一個字符串以進行凹痕,很方便有效地有一種有效的方法來返回字符串重複指定的次數的字符串。使用指定的次數。 constructor 這將返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.W...
    程式設計 發佈於2025-06-07
  • 使用jQuery如何有效修改":after"偽元素的CSS屬性?
    使用jQuery如何有效修改":after"偽元素的CSS屬性?
    在jquery中了解偽元素的限制:訪問“ selector 嘗試修改“:”選擇器的CSS屬性時,您可能會遇到困難。 This is because pseudo-elements are not part of the DOM (Document Object Model) and are th...
    程式設計 發佈於2025-06-07
  • Android如何向PHP服務器發送POST數據?
    Android如何向PHP服務器發送POST數據?
    在android apache httpclient(已棄用) httpclient httpclient = new defaulthttpclient(); httppost httppost = new httppost(“ http://www.yoursite.com/script.p...
    程式設計 發佈於2025-06-07
  • 如何實時捕獲和流媒體以進行聊天機器人命令執行?
    如何實時捕獲和流媒體以進行聊天機器人命令執行?
    在開發能夠執行命令的chatbots的領域中,實時從命令執行實時捕獲Stdout,一個常見的需求是能夠檢索和顯示標準輸出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    程式設計 發佈於2025-06-07
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP將...
    程式設計 發佈於2025-06-07
  • 如何使用替換指令在GO MOD中解析模塊路徑差異?
    如何使用替換指令在GO MOD中解析模塊路徑差異?
    在使用GO MOD時,在GO MOD 中克服模塊路徑差異時,可能會遇到衝突,其中3個Party Package將另一個PAXPANCE帶有導入式套件之間的另一個軟件包,並在導入式套件之間導入另一個軟件包。如迴聲消息所證明的那樣: go.etcd.io/bbolt [&&&&&&&&&&&&&&&&...
    程式設計 發佈於2025-06-07
  • 如何使用Java.net.urlConnection和Multipart/form-data編碼使用其他參數上傳文件?
    如何使用Java.net.urlConnection和Multipart/form-data編碼使用其他參數上傳文件?
    使用http request 上傳文件上傳到http server,同時也提交其他參數,java.net.net.urlconnection and Multipart/form-data Encoding是普遍的。 Here's a breakdown of the process:Mu...
    程式設計 發佈於2025-06-07
  • Java字符串非空且非null的有效檢查方法
    Java字符串非空且非null的有效檢查方法
    檢查字符串是否不是null而不是空的 if(str!= null && str.isementy())二手: if(str!= null && str.length()== 0) option 3:trim()。 isement(Isement() trim whitespace whites...
    程式設計 發佈於2025-06-07
  • CSS可以根據任何屬性值來定位HTML元素嗎?
    CSS可以根據任何屬性值來定位HTML元素嗎?
    靶向html元素,在CSS 中使用任何屬性值,在CSS中,可以基於特定屬性(如下所示)基於特定屬性的基於特定屬性的emants目標元素: 字體家庭:康斯拉斯(Consolas); } 但是,出現一個常見的問題:元素可以根據任何屬性值而定位嗎?本文探討了此主題。 的目標元素有任何任何屬性值,...
    程式設計 發佈於2025-06-07
  • 如何在JavaScript對像中動態設置鍵?
    如何在JavaScript對像中動態設置鍵?
    在嘗試為JavaScript對象創建動態鍵時,如何使用此Syntax jsObj['key' i] = 'example' 1;不工作。正確的方法採用方括號: jsobj ['key''i] ='example'1; 在JavaScript中,數組是一...
    程式設計 發佈於2025-06-07
  • Python中嵌套函數與閉包的區別是什麼
    Python中嵌套函數與閉包的區別是什麼
    嵌套函數與python 在python中的嵌套函數不被考慮閉合,因為它們不符合以下要求:不訪問局部範圍scliables to incling scliables在封裝範圍外執行範圍的局部範圍。 make_printer(msg): DEF打印機(): 打印(味精) ...
    程式設計 發佈於2025-06-07
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。 The fd.append("fileToUpload[]", files[x]); method can be used for this purpose, allowing you to send multi...
    程式設計 發佈於2025-06-07
  • 為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    查詢模式實現缺失:解決“無法找到”錯誤在銀光應用程序中,嘗試使用LINQ建立錯誤的數據庫連接的嘗試,無法找到以查詢模式的實現。 ”當省略LINQ名稱空間或查詢類型缺少IEnumerable 實現時,通常會發生此錯誤。 解決問題來驗證該類型的質量是至關重要的。在此特定實例中,tblpersoon可能...
    程式設計 發佈於2025-06-07
  • 為什麼Microsoft Visual C ++無法正確實現兩台模板的實例?
    為什麼Microsoft Visual C ++無法正確實現兩台模板的實例?
    The Mystery of "Broken" Two-Phase Template Instantiation in Microsoft Visual C Problem Statement:Users commonly express concerns that Micro...
    程式設計 發佈於2025-06-07

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3