Eine detaillierte Diskussion der Auswertungsstrategien in JavaScript

Eine detaillierte Diskussion der Auswertungsstrategien in JavaScript

Ich habe kürzlich die Anwendung der η-Transformation in der Lambda-Rechnung in JavaScript studiert und bin zufällig auf eine interessante Frage auf Stackoverflow gestoßen. Erfolgt die Parameterübergabe von Funktionen in JS im Hinblick auf die Auswertungsstrategie von JavaScript per Wert oder per Referenz? Die Antwort ist klassisch.

Eine Kastanie zum Abdecken

Funktion changeStuff(a, b, c) {
  a = a * 10;
  b.item = "geändert";
  c = {item: "geändert"};
}

varnum = 10;
var obj1 = {item: "unverändert"};
var obj2 = {item: "unverändert"};

ändereStuff(Anzahl, Objekt1, Objekt2);

console.log(num); // 10
console.log(obj1.item); // geändert
console.log(obj2.item); // unverändert

Wenn die Parameterübergabe der Funktion in js als Wert erfolgt, hat eine Änderung des Werts von b.item innerhalb der Funktion changeStuff keine Auswirkungen auf den Wert des externen Objekts obj1.

Wenn die Funktionsparameter in JS per Einführung übergeben werden, wirken sich die innerhalb der Funktion changeStuff vorgenommenen Änderungen auf alle Variablendefinitionen außerhalb der Funktion aus. num wird beispielsweise zu 100 und obj2.item wird geändert. Dies ist offensichtlich nicht der Fall.

Wir können also nicht sagen, dass die Übergabe von Funktionsparametern in JS streng nach Wert oder Einführung erfolgt. Im Allgemeinen werden Funktionsparameter als Wert übergeben. JS verwendet auch eine Parameterübergabestrategie namens „Shared Passing“. Dies hängt vom Typ des Parameters ab.

Wenn der Parameter ein primitiver Typ ist, wird er als Wert übergeben.

Wenn der Parameter ein Referenztyp ist, wird er als gemeinsam genutzt übergeben.

Parameterübergabe

Alle Funktionsparameter in ECMAScript werden als Wert übergeben. Das heißt, das Kopieren eines Werts außerhalb einer Funktion in einen Parameter innerhalb der Funktion ist dasselbe wie das Kopieren eines Werts von einer Variablen in eine andere. Die Übertragung von Werten des primitiven Typs entspricht dem Kopieren von Variablen des primitiven Typs, während die Übertragung von Werten des Referenztyps dem Kopieren von Variablen des Referenztyps entspricht. -- Fortgeschrittene JavaScript-Programmierung

Im Red Book steht, dass alle Funktionsparameter als Wert übergeben werden. Stimmt das? Lassen Sie uns das obige Beispiel analysieren:

Übergabe nach Wert

Die Strategie für primitive Typen als Parameter in JavaScript besteht in der Übergabe per Wert (Call by Value):

Funktion foo(a) {
  a = a * 10;
}

varnum = 10;

foo(Nummer);

console.log(num); // 10 keine Änderung

Hier können wir sehen, dass Änderungen der internen Parameter der Funktion keine Auswirkungen auf die externen Variablen haben. Die Übergabe nach Wert ist korrekt.

Per Sammellieferung

Die Strategie zum Übergeben von Objekten als Parameter in JavaScript ist „Call by Sharing“:

Das Ändern der Eigenschaften eines Parameters wirkt sich auf externe Objekte aus

Die Neuzuweisung hat keine Auswirkungen auf externe Objekte

Gemäß dem obigen Beispiel wird das Eigenschaftselement des Parameters b innerhalb der Funktion geändert, was sich auf das Objekt außerhalb der Funktion auswirkt, sodass auch das Eigenschaftselement von Objekt1 geändert wird.

Funktion bar(b) {
  b.item = "geändert";
  console.log(b === obj1) // wahr
}

var obj1 = {item: "unverändert"};

Balken(Objekt1);

console.log(obj1.item); // geändert Das Ändern der Eigenschaften der Parameter wirkt sich auf das externe Objekt aus

Da das Druckergebnis von b === obj1 wahr ist, können wir erkennen, dass die Änderung des Attributs des Parameters innerhalb der Funktion keinen Einfluss auf die Referenz des Parameters hat. b und obj1 teilen sich eine Objektadresse, daher wirkt sich das Ändern der Eigenschaften des Parameters auf das externe Objekt aus.

Die Neuzuweisung des Parameters c zu einem neuen Objekt hat keine Auswirkungen auf das externe Objekt.

Funktion baz(c) {
  c = {item: "geändert"};
  console.log(c === obj2) // falsch
}

var obj2 = {item: "unverändert"};

baz(Objekt2);

console.log(obj2.item); // unverändert Die Neuzuweisung hat keine Auswirkungen auf das externe Objekt

Weisen Sie den Parameter c einem neuen Objekt zu. Dann wird c an eine neue Objektadresse gebunden und c === obj2 gibt „false“ aus, was bedeutet, dass sie nicht mehr dieselbe Objektadresse haben. Sie verfügen jeweils über eine eigene Objektadresse. Eine Neuzuweisung hat daher keine Auswirkungen auf das externe Objekt.

Zusammenfassen

Man kann sagen, dass die Weitergabe durch Teilen ein Sonderfall der Weitergabe durch Wert ist, bei dem eine Kopie der Referenzadresse weitergegeben wird. Was im Kleinen Roten Buch steht, ist also richtig.

Sie können sich die Parameter einer ECMAScript-Funktion als lokale Variablen vorstellen. -- Fortgeschrittene JavaScript-Programmierung

Erweiterung - Lazy Evaluation

Wir haben früher gelernt, dass alle Funktionsparameter als Wert übergeben werden. In JavaScript müssen Parameter zuerst ausgewertet und dann als tatsächliche Parameter an die Funktion übergeben werden. In ES6 gibt es jedoch einen Sonderfall.

Der Standardwert des Parameters wird nicht als Wert übergeben, sondern der Wert des Standardwertausdrucks wird jedes Mal neu berechnet. Das heißt, die Standardwerte der Parameter werden verzögert ausgewertet. - „ECMAScript 6-Grundlagen“

sei x = 99;
Funktion foo(p = x + 1) {
  konsole.log(p);
}

foo() // 100

x = 100;
foo() // 101

Im obigen Code ist der Standardwert des Parameters p x + 1. Zu diesem Zeitpunkt wird bei jedem Aufruf der Funktion foo x + 1 neu berechnet, anstatt des Standardwerts p gleich 100

Oben finden Sie eine ausführliche Diskussion der Auswertungsstrategie in JavaScript. Weitere Informationen zur Auswertungsstrategie in JavaScript finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Vertieftes Verständnis der JavaScript-Reihe (19): Detaillierte Erläuterung der Bewertungsstrategie
  • So schreiben Sie einen Meta-Zirkel-Evaluator für Javascript
  • Ein Beispiel für eine Methode zur Implementierung der Lazy Evaluation in JavaScript
  • JS implementiert ein Beispiel für eine Taschenrechnerfunktion, die arithmetische Ausdrücke auswerten kann
  • Detaillierte Erläuterung des Problems der Ausdrucksauswertung bei der Anwendung des Stapels in der JavaScript-Datenstruktur
  • Anwendungsbeispiele für JS-Closure und verzögerte Auswertung
  • Javascript-Operandenauswertungsreihenfolge
  • JavaScript+HTML zur Implementierung eines Studenteninformationsmanagementsystems
  • Detaillierte Erklärung dieses Zeigeproblems in JavaScript
  • Verschaffen Sie sich ein umfassendes Verständnis des Prototypobjekts in JavaScript

<<:  Detaillierte Erläuterung der Frp-erzwungenen Umleitung zur https-Konfiguration unter Nginx

>>:  Lösen Sie das Problem, dass VMWare nach der Installation des Mac-Systems nicht im Vollbildmodus angezeigt werden kann

Artikel empfehlen

Vue Storage enthält eine Lösung für Boolesche Werte

Vue speichert Speicher mit Booleschen Werten Ich ...

Mysql-Sortierung und Paginierung (Order by & Limit) und vorhandene Fallstricke

Sortierabfrage (Sortieren nach) Im E-Commerce: Wi...

Zusammenfassung aller HTML-Interviewfragen

1. Die Rolle des Doctypes, der Unterschied zwisch...

Eine detaillierte Erklärung der subtilen Unterschiede zwischen Readonly und Disabled

Sowohl die Optionen „Nur lesen“ als auch „Deaktivi...

So zeigen Sie die Zeitzone in MySQL an und ändern sie

Heute habe ich festgestellt, dass ein Programm ei...

So richten Sie eine VSCode-Remoteverbindung zum Server-Docker-Container ein

Inhaltsverzeichnis Ziehen Sie das Bild Ausführen ...

Vue Grundanleitung Beispiel grafische Erklärung

Inhaltsverzeichnis 1. v-on-Richtlinie 1. Grundleg...

Lösung zum Vergessen des Passworts des Pagodenpanels in Linux 3.X/4.x/5.x

Geben Sie ssh ein und geben Sie den folgenden Bef...

So fügen Sie Nginx zu den Systemdiensten in CentOS7 hinzu

Einführung Nach dem Kompilieren, Installieren und...

So führen Sie geplante PHP-Aufgaben in CentOS7 aus

Vorwort Dieser Artikel stellt hauptsächlich den r...