Heim > Web-Frontend > js-Tutorial > Übernehmen Sie die Kontrolle über Schleifen mit Symbol.iterator

Übernehmen Sie die Kontrolle über Schleifen mit Symbol.iterator

Linda Hamilton
Freigeben: 2024-11-08 07:16:02
Original
837 Leute haben es durchsucht

Take control of loops with Symbol.iterator

Haben Sie jemals ein Object.entries verwendet und sich gefragt, wie es funktioniert? Es ist viel einfacher als Sie denken!

Hier ist eine grundlegende Implementierung:

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

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

  return entries;
}
Nach dem Login kopieren
Nach dem Login kopieren

Dieser Code ist jedoch nicht ganz gut genug – was wäre, wenn das Objekt massiv wäre? Die Leistung des Array-basierten Ansatzes muss für den gesamten Prozess der Ausführung dieser Funktion im Speicher gespeichert werden. Und wenn Sie es noch einmal verwenden? Es muss trotzdem ein neues Array erstellt und im Speicher gehalten werden. In der realen Welt kann dies zu ernsthaften Leistungsproblemen führen und irgendwann müssen wir uns auf die Leistung einstellen. Es gibt jedoch eine elegante Lösung, die all diese Probleme löst: Symbol.iterator kommt zur Rettung!

Hier ist ein aktualisierter Ausschnitt:

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

      return {
        next() {
          if (index < keys.length) {
            const key = keys[index++];
            return { value: [key, obj[key]], done: false };
          }
          return { done: true };
        }
      };
    }
  };
}
Nach dem Login kopieren
Nach dem Login kopieren

Warum Symbol.iterator für die Iteration verwenden?

In unserer ersten Implementierung erstellt die Funktion „objectEntries“ ein Array aller Einträge ([Schlüssel, Wert]-Paare) im Speicher, was ein Problem sein kann, wenn das Objekt eine große Anzahl von Eigenschaften hat. Das Speichern aller Einträge in einem Array bedeutet, dass wir jedem einzelnen Paar im Voraus Speicher zuweisen müssen. Dieser Ansatz ist für kleinere Objekte einigermaßen in Ordnung, wird jedoch mit zunehmender Objektgröße schnell ineffizient und einfach langsamer.

Im aktualisierten Code definieren wir [Symbol.iterator] für ein Objekt, das die Iterationslogik enthält. Lassen Sie es uns Schritt für Schritt aufschlüsseln:

  • Schlüssel initialisieren: Object.keys(obj) ruft ein Array von Schlüsseln vom Objekt obj ab. Mithilfe dieser Schlüsselliste können wir genau wissen, auf welche Eigenschaften wir zugreifen müssen, ohne jeden Eintrag speichern zu müssen.
  • Verwenden Sie einen Indexzeiger: Ein variabler Index verfolgt unsere aktuelle Position im Schlüsselarray. Dies ist der einzige Zustand, den wir in der Schleife haben werden.
  • Definieren Sie die nächste Methode: Die Funktion next() verwendet den Index, um den aktuellen Schlüssel abzurufen und ihn zu erhöhen. Es gibt jedes [key, obj[key]]-Paar als Wert zurück und setzt done: true, wenn wir alle Schlüssel durchlaufen haben.
  • Auf diese Weise ermöglichen wir, dass objectEntries mit jeder for...of-Schleife kompatibel sind, ohne dass die Speicherkosten für die vorherige Erstellung eines ganzen Arrays von Einträgen anfallen.

Symbol.iterator auf benutzerdefinierte Schleifen anwenden

Lassen Sie uns genauer untersuchen, wie diese Methoden eine bessere Kontrolle über das Schleifenverhalten ermöglichen können. Jedes der bereitgestellten Beispiele zeigt eine einzigartige Möglichkeit, mit Array-Daten zu interagieren und Ihrem Code viel Flexibilität zu verleihen. Wir werden die Auswirkungen jeder Methode untersuchen und wie sie in verschiedenen Szenarien eingesetzt werden können.

In diesen Beispielen werde ich den Array-Prototyp (weitere Informationen zu Prototypen finden Sie hier) mit den Beispielmethoden erweitern, um die Lesbarkeit meines Codes zu verbessern. Lasst uns gleich einsteigen!

Diese ReverseIterator-Methode kann beispielsweise in einer Chat-Anwendung nützlich sein, in der Sie möglicherweise die neuesten Nachrichten zuerst anzeigen möchten. Chat-Anwendungen sind bekannt dafür, dass sie eine Menge Daten (in diesem Fall Nachrichten) enthalten. Mit reverseIterator können Sie eine Liste von Nachrichten durchlaufen und sie in der gewünschten Reihenfolge anzeigen, ohne ein neues umgekehrtes Array erstellen zu müssen.

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

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

  return entries;
}
Nach dem Login kopieren
Nach dem Login kopieren

Mit dieser einzigartigen Methode können Sie ein Array durchlaufen und dabei sicherstellen, dass nur eindeutige Werte zurückgegeben werden. Dies ist sehr nützlich, um Duplikate im Handumdrehen zu entfernen, ohne sie vorher zu filtern und mehr Speicher zu verbrauchen.

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

      return {
        next() {
          if (index < keys.length) {
            const key = keys[index++];
            return { value: [key, obj[key]], done: false };
          }
          return { done: true };
        }
      };
    }
  };
}
Nach dem Login kopieren
Nach dem Login kopieren

Die folgende Chunk-Methode kann beim Umgang mit großen Datensätzen hilfreich sein. Sie können diese in kleineren Chunks verarbeiten, um die Speichernutzung zu reduzieren und die Leistung zu verbessern. Nehmen wir an, Sie importieren Daten aus einer CSV-Datei und können sie in besser skalierbaren Segmenten lesen und verarbeiten. Darüber hinaus kann Chunking in Web-Benutzeroberflächen für die Paginierung verwendet werden, sodass Sie eine bestimmte Anzahl von Elementen pro Seite anzeigen oder einen Infinite Loader besser verwalten können.

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
}
Nach dem Login kopieren

Fazit

In diesem Artikel haben wir untersucht, wie Symbol.iterator die Logik anpasst und die Effizienz unserer Schleifen verbessert. Durch die Implementierung benutzerdefinierter iterierbarer Methoden auf dem Array.prototype (oder einer anderen zu diesem Zweck iterierbaren Methode) können wir die Speichernutzung effektiv verwalten und steuern, wie unsere Schleife ausgeführt wird.

Das erste Beispiel von objectEntries zeigte, wie ein Array-basierter Ansatz bei der Verarbeitung großer Objekte zu Leistungsproblemen führen kann. Durch die Verwendung des SYmbol.iterator haben wir jedoch eine effiziente Lösung geschaffen, die es uns ermöglicht, über Objekteinträge zu iterieren, ohne den Aufwand einer unnötigen Speicherzuweisung.

Wir haben uns auch mehrere praktische Beispiele angesehen, wie die Erweiterung des Array.prototype verschiedene reale Szenarien erleichtern kann, mit denen sich Entwickler täglich auseinandersetzen müssen.

Mit diesen leistungsstarken Tools sind Sie besser gerüstet, um komplexe Datenverarbeitungsszenarien in JavaScript zu lösen, ohne dass sich dies auf die Leistung Ihrer App auswirkt.

Das obige ist der detaillierte Inhalt vonÜbernehmen Sie die Kontrolle über Schleifen mit Symbol.iterator. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage