So überwachen Sie Array-Änderungen in JavaScript

So überwachen Sie Array-Änderungen in JavaScript

Vorwort

Als ich zuvor „defineProperty“ vorgestellt habe, habe ich erwähnt, dass es nur Änderungen an Objekten überwachen kann, nicht jedoch Änderungen in Arrays.

In diesem Artikel wird erläutert, wie Array-Änderungen überwacht werden.

Kernidee: Finden Sie Wege, das ursprüngliche Array zu ändern, und kapern Sie dann diese Methoden.

Der obige Satz ist von größter Wichtigkeit. Lesen Sie ihn unbedingt dreimal und merken Sie ihn sich, bevor Sie fortfahren.

Zu den häufig verwendeten Methoden zum Ändern des ursprünglichen Arrays zählen Push, Pop, Shift und Unshift, Reverse, Sort und Splice.

Mit anderen Worten: Diese Methoden ändern die Einträge des Arrays.

Fügen Sie zwischen der Array-Instanz und dem Array-Prototyp einen neuen Prototyp hinzu

Die direkte Änderung von Array.prototype ist äußerst gefährlich.

Ändern Sie Ihre Meinung, kopieren Sie den vorhandenen Array-Prototyp und ändern Sie dann die Methoden darin. Hier können die Methoden des Prototyps jedoch nicht kopiert werden, da sie nicht aufzählbar sind.

Ändern wir also unsere Denkweise. Wir können einen Prototyp zwischen dem Array und dem Prototyp des Arrays einfügen, um eine Prototypenkette zu bilden: Array => neuer Prototyp => Prototyp des Arrays. Wir können dann dem neuen Prototyp eine Methode mit demselben Namen hinzufügen.

Verwenden Sie zunächst Pseudocode, um Folgendes zu verstehen:

// Pseudocode let arr = [];
arr.__proto__ = neuer Prototyp;
neuerPrototype.__proto__ = Array.prototype;
// Dann können Sie dem neuen Prototyp eine Methode mit demselben Namen hinzufügen newPrototype.push = xxx;

Der eigentliche Code lautet wie folgt. Der Kern verwendet Object.create.

// Object.create gibt ein neues Objekt zurück und das __proto__ des neuen Objekts ist der übergebene Parameter.
Fügt neue Prototypen zu Object.create(Array.prototype);
// Dann können Sie dem neuen Prototyp eine Methode mit demselben Namen hinzufügen newPrototype.push = xxx;

// Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = [];
arr.__proto__ = neuer Prototyp;

Nehmen Sie Push als Beispiel, kapern Sie Push

Schreiben Sie dazu einfach eine Push-Methode auf den neuen Prototypen, die den alten Push ausführt, aber auch noch etwas anderes kann.

Fügt neue Prototypen zu Object.create(Array.prototype);

// Füge dem neuen Prototyp einen Push mit dem gleichen Namen hinzu
neuerPrototype.push = Funktion(...args) {
  // Semantisches dies
  lass curArr = dies;
  console.log("Push wird verwendet");
  // Abschließend wird der ursprüngliche Push ausgeführt
  gibt Array.prototype.push.call(curArr, ...args) zurück;
};

// Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = [];
arr.__proto__ = neuer Prototyp;

// Wenn Push ausgeführt wird, wird arr.push(1) gedruckt;

Dann sind andere Methoden ähnlich. Versuchen Sie, andere Methoden zu schreiben

Andere Methoden kapern

Die anderen Methoden werden auch zusammen geschrieben, da die Logik dieselbe ist und direkt durchlaufen werden kann.

Fügt neue Prototypen zu Object.create(Array.prototype);

let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"];

Methoden.fürJedes(Methode => {
  neuerPrototyp[Methode] = Funktion(...Argumente) {
    console.log(`${method} verwendet`);
    gibt Array.prototype[Methode].call(diese, ...args) zurück;
  };
});

// Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = [];
arr.__proto__ = neuer Prototyp;

// Bei der Ausführung wird arr.push(1) gedruckt;
arr.pop();

Wenn das Array Array-Elemente enthält, müssen diese ebenfalls überwacht werden

Hier kann sich ein Array im Array befinden, und jedes Element im Array muss durchlaufen werden. Wenn es sich um ein Array handelt, muss es dennoch auf den neuen Prototyp verweisen.

Ja, es wird Rekursion verwendet.

Fügt neue Prototypen zu Object.create(Array.prototype);

let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"];

Methoden.fürJedes(Methode => {
  neuerPrototyp[Methode] = Funktion(...Argumente) {
    console.log(`${method} verwendet`);
    gibt Array.prototype[Methode].call(diese, ...args) zurück;
  };
});

Funktion beobachteArr(arr) {
  // Es ist sowohl eine bedingte Einschränkung als auch eine rekursive Abbruchbedingung, wenn (!Array.isArray(arr)) {
    zurückkehren;
  }
  // Das gesamte Array zeigt auf den neuen Prototyp arr.__proto__ = newPrototype;
  // Jedes Element im Array, sofern es ein Array ist, verweist auch auf den neuen Prototyp.
  arr.forEach(beobachtenArr);
}
// Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = [[1, 2, 3]];
beobachteArr(arr);

// Bei der Ausführung wird arr[0].push(1) gedruckt;
arr[1].pop();

Neue Elemente, die dem Array hinzugefügt werden, müssen, wenn es sich um ein Array handelt, auch auf den neuen Prototyp verweisen

Methoden, die Elemente hinzufügen können: Push, Unshift, Splice.

Suchen Sie nach dem neu hinzugefügten Element. Anschließend zeigt das Array auch auf den neuen Prototyp

Fügt neue Prototypen zu Object.create(Array.prototype);

let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"];

Methoden.fürJedes(Methode => {
  neuerPrototyp[Methode] = Funktion(...Argumente) {
    console.log(`${method} verwendet`);
    eingefügt lassen;
    Schalter (Methode) {
      Fall "push":
      Fall "unshift":
        eingefügt = Argumente;
        brechen;
      Fall "Spleißen":
        eingefügt = args.slice(2);
        brechen;
      Standard:
        brechen;
    }
    eingefügt und observeArr (eingefügt);
    gibt Array.prototype[Methode].call(diese, ...args) zurück;
  };
});

Funktion beobachteArr(arr) {
  // Es ist sowohl eine bedingte Einschränkung als auch eine rekursive Abbruchbedingung, wenn (!Array.isArray(arr)) {
    zurückkehren;
  }
  // Das gesamte Array zeigt auf den neuen Prototyp arr.__proto__ = newPrototype;
  // Jedes Element im Array, sofern es ein Array ist, verweist auch auf den neuen Prototyp.
  arr.forEach(beobachtenArr);
}
// Dies kann exportiert werden, um die Verwendung anderer Dateien zu erleichtern. Exportieren Sie standardmäßig „objectArr“.
// Zu überwachendes Array, binden Sie einfach den neuen Prototyp let arr = [];
beobachteArr(arr);
Lassen Sie addItem = [1, 2, 3];
arr.push(Element hinzufügen);
// Bei der Ausführung wird addItem.push(1) gedruckt;
addItem.pop();

Kombinierte Verwendung von defineProperty zur Überwachung von Objekten und Arrays

Jetzt haben wir Methoden zum Überwachen von Objekten und Methoden zum Überwachen von Arrays. Durch die Kombination der beiden können wir Objekte in Arrays und Arrays in Objekten überwachen.

Das Überwachungsarray und das Überwachungsobjekt können zur späteren Verwendung in eine separate Datei geschrieben werden.

Um die direkte Codeausführung zu ermöglichen, werden sie hier zusammengefasst.

/**
 * observeArr-Teil**/
// Einen neuen Prototyp generieren let newPrototype = Object.create(Array.prototype);

let-Methoden = ["push", "pop", "shift", "unshift", "reverse", "sort", "spleißen"];
// Füge die obige Methode zum neuen Prototyp hinzu, um methods.forEach(method => { zu kapern.
  neuerPrototyp[Methode] = Funktion(...Argumente) {
    console.log(`${method} verwendet`);
    eingefügt lassen;
    Schalter (Methode) {
      Fall "push":
      Fall "unshift":
        eingefügt = Argumente;
        brechen;
      Fall "Spleißen":
        eingefügt = args.slice(2);
        brechen;
      Standard:
        brechen;
    }
    eingefügt und observeArr (eingefügt);
    gibt Array.prototype[Methode].call(diese, ...args) zurück;
  };
});

Funktion beobachteArr(arr) {
  // Neu! ! ! Wenn es ein Objekt ist, müssen Sie das Objekt verwenden, wenn (Object.prototype.toString.call(arr) === "[object Object]") {
    beobachteObj(arr);
    zurückkehren;
  }

  wenn (Array.isArray(arr)) {
    // Das gesamte Array zeigt auf den neuen Prototyp arr.__proto__ = newPrototype;
    // Jedes Element im Array, sofern es ein Array ist, verweist auch auf den neuen Prototyp.
    arr.forEach(beobachtenArr);
  }

  // Kein Objekt oder Array, nichts tun}

/**
 * observeObj-Teil**/
Funktion Obj beobachten(Objekt) {
  // Parameterbeschränkungen hinzufügen, es können nur Objekte gekapert werden, was auch die Abbruchbedingung der Rekursion ist, wenn (typeof obj !== "object" || obj == null) {
    zurückkehren;
  }
  // Neu! ! ! Array wird zur Verarbeitung an Array übergeben, wenn (Array.isArray(obj)) {
    beobachteArr(Objekt);
    zurückkehren;
  }
  // Rekursion nur starten, wenn es sich um ein Objekt handelt for (let key in obj) {
    // Die direkte Verwendung von obj.hasOwnProperty führt zu einem nicht standardmäßigen if (Object.prototype.hasOwnProperty.call(obj, key)) {
      observeKey(Objekt, Schlüssel);
      // Hier wird der Attributwert des Attributs gekapert. Wenn es kein Objekt ist, wird es direkt zurückgegeben, ohne Auswirkungen auf observeObj(obj[key]);
    }
  }
  gibt Objekt zurück;
}
Funktion observeKey(Objekt, Schlüssel) {
  let value = obj[Schlüssel];
  Objekt.defineProperty(Objekt, Schlüssel, {
    erhalten() {
      console.log("Eigenschaften lesen", Wert);
      Rückgabewert;
    },
    setze(neuerWert) {
      console.log("Eigenschaften festlegen", neuerWert);
      Wert = neuerWert;
    }
  });
}

/**
 * Probieren Sie die Demo aus**/
lass Daten = { a: 1, b: [1, 2, { c: 2 }] };
Obj beobachten(Daten);
Daten.a = 2;
daten.b.push([2, 3]);

let arr = [{ a: "Objekt im Array" }, 3, 4];
beobachteArr(arr);
arr[0].a = 3;

Defekt

Natürlich können Arrays auch ohne Methoden verändert werden. So kann man beispielsweise ein Array löschen, indem man das Längenattribut verwendet, oder man kann das Array direkt verändern, indem man arr[0]=xxx verwendet.

Array-Änderungen können jedoch nur bei Verwendung von „Push“, „Pop“, „Shift“, „Unshift“, „Reverse“, „Sort“ und „Splice“ erkannt werden.

Dies ist auch ein Defekt von Vue. Natürlich wird die neue Version des Proxys diesen Defekt beheben.

Versuchen Sie daher bei Verwendung von Vue, das Array mit der oben beschriebenen Methode zu betreiben~~~

Hinweis: Alle Eigenschaften und Methoden von Arrays anzeigen

Sie können dir([]) in die Konsole eingeben und dann alle Eigenschaften und Methoden des Arrays sehen.

Für spezifische Verwendungszwecke können Sie direkt zu mdn gehen und auf die Seitenleiste klicken, um die entsprechende Methode anzuzeigen

Zusammenfassen

Dies ist das Ende dieses Artikels zum Überwachen von Array-Änderungen mit JavaScript. Weitere relevante Inhalte zum Überwachen von Array-Änderungen mit JS finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Ein Artikel, der Ihnen hilft, mehr über JavaScript-Arrays zu erfahren
  • Detaillierte Erläuterung mehrerer Methoden zur Deduplizierung im Javascript-Array
  • Detaillierte Erklärung der integrierten Methoden des Javascript-Arrays
  • Häufig verwendete JavaScript-Array-Methoden
  • Detaillierte Zusammenfassung des JavaScript-Arrays
  • JavaScript verwendet häufig Array-Deduplizierung tatsächliche Kampf Quellcode
  • Beispiele und Vergleich von 3 Methoden zur Deduplizierung von JS-Objekt-Arrays
  • JS implementiert Array-Filterung von einfacher bis hin zu Multi-Condition-Filterung
  • Syntax und Beispielanalyse der JavaScript-Array-Methode „reduce()“
  • Implementieren Sie über 24 Array-Methoden in JavaScript von Hand

<<:  Implementierungsschritte zum Erstellen eines lokalen Webservers auf Centos8

>>:  So ändern Sie das Root-Benutzerkennwort in MySQL 8.0.16, WinX64 und Linux

Artikel empfehlen

Tabelle der durch hasLayout verursachten CSS-Fehler

Der IE hat schon seit längerem Probleme. Als alle ...

Analyse von 2 Token-Gründen und Beispielcode in der Webprojektentwicklung

Inhaltsverzeichnis Frage: Es gibt 2 Token im Proj...

Warum Google und Facebook Docker nicht verwenden

Der Grund für das Schreiben dieses Artikels beste...

Eine Zusammenfassung der Fuzzy-Abfrage von MySQL wie

1. Allgemeine Verwendung: (1) Mit % verwenden % s...

JS beherrscht schnell die Verwendung von ES6-Klassen

1. Wie konstruieren? Lassen Sie uns die allgemein...

Erfahrungsaustausch durch einen Frontend-Supervisor mit 7 Jahren Praxiserfahrung

Heute teile ich die wertvollen Erfahrungen eines ...

Tutorial zur MySQL-Installation unter Linux (Binärdistribution)

Dieses Tutorial beschreibt Ihnen die detaillierte...

So verwenden Sie CSS-Attributselektoren zum Spleißen von HTML-DNA

CSS-Attributselektoren sind großartig. Sie können...

Häufige Fehler und Gründe für MySQL-Verbindungsfehler

=================================================...

Lösung für falsche Zeichenfolgenwerte in MySQL

Viele Freunde berichten von folgendem Fehler, wen...

Auszeichnungssprache - Stylesheets drucken

Klicken Sie hier, um zum Abschnitt „HTML-Tutorial“...