2017-09-24 1 views
4

Ich habe die Frage und Antwort hier lesen:Warum sind die Zahlen in Javascript unveränderlich?

javascript numbers- immutable

Aber es ist nicht genug für mich klar, warum die Zahl (Urtyp) unveränderlich ist? Nur weil sie eine neue Referenz erstellen, aber den Wert nicht überschreiben?

Wenn auf jedem assignemt erstellt eine neue Referenz

var x = 5; 
x = 1; 

Würden wir 100-mal eine neue Referenz in der folgenden Schleife haben?

while (x < 101) 
{ 
    x++; 
} 

Ist das effizient? Ich denke, ich sehe nicht richtig.

+5

Was würde es bedeuten, wenn die Zahl 5 veränderbar wäre? – Pointy

+0

Lesen Sie die Antwort in der Frage, die Sie verknüpft haben: Die Zahlen selbst sind unveränderlich (oder Sie könnten Konstanten sagen). Die Variable x ist eine Referenz auf eine Zahl/Konstante. Dort steht auch, dass es in allen Programmiersprachen gleich ist. Sonst könnten Sie Zahlen entfernen/überschreiben und die ganze Mathematik/Berechnungen, die die Sprache machen kann, vermasseln. Recht? –

+0

Mmm aber wenn die Zahl etwas Konstanten sind, warum können wir sie Werte wieder aktivieren? x = 5 dann x = 1. – Jamo

Antwort

1

Zahlen sind unveränderlich, weil es für sie Sinn macht, unveränderlich zu sein: die Zahl 5 ist die Zahl 5, es hat keinen Sinn, das Objekt selbst zu verändern.

Wenn Sie so etwas wie:

let x = 5; 

Sie haben das Objekt 5 und die Variable x die 5 das Objekt verweist. Wenn Sie dann x ändern:

x = 4; 

Sie sind nicht das Objekt zu ändern 5: was Sie ändern ist, was die Variable x zu zeigt.

In Ihrem while Beispiel gibt es die verschiedenen numerischen Konstanten 0, 1, 2, ... und die Variable x: bei jeder Iteration, die x++ die numerischen Konstanten Änderungen an, die an die Variable x zeigt.

Eine ähnliche Argumentation kann auf viele Sprachen angewendet werden, nicht nur auf Javascript: In der Tat, Zahlen in vielen Sprachen und oft Strings sind unveränderliche Objekte und ähnliche Regeln folgen


EDIT: Wie in den Kommentaren darauf hingewiesen In JavaScript-Nummern sind primitive Werte und keine Objekte (obwohl sie in ein Objekt der Klasse Number eingeschlossen werden können). Daher ändern Sie nicht wirklich die Referenz, auf die x zeigt, da keine Objekte beteiligt sind: Sie aktualisieren direkt den primitiven Wert. Felix Klings Antwort ist angemessener.

+0

Okay, wenn ich das Objekt 5 nicht verändere und nur auf was die Variable x zeigt, was passiert mit Objekt 5, nachdem ich einen anderen Wert zu x zugewiesen habe? – Jamo

+0

@jamo: Je nachdem, wo es zugeordnet ist, wird es automatisch freigegeben, wenn der aktuelle Ausführungskontext verlassen wird, oder es wird Müll gesammelt, wenn es keinen anderen Verweis darauf gibt. –

+1

5 ist kein Objekt. Es ist ein primitiver Wert. x enthält keinen Verweis auf Objekt 5. x wird die Zahl 5 als x-Wert enthalten. –

-1

Primitive Werte vs. Referenzen:

In JavaScript Werten vom Typ boolean, nicht definiert, null, Anzahl, Symbol, string sind primitiv. Wenn Sie sie einer Variablen zuweisen oder als Argument an eine Funktion übergeben, werden sie immer kopiert. Im Gegensatz dazu haben Objekte zwei Teile: Objekte (ihre Daten) werden in einem Teil des Speichers gespeichert und was Sie einer Variablen zuweisen, ist eine Referenz, die auf dieses Objekt zeigt. Das Objekt selbst wird bei der Zuweisung nicht kopiert.

Da Zahlen immer kopiert werden, wenn Sie sie einer Variablen zuweisen, ist es unmöglich, eine Zahl zu ändern und diese Änderung durch eine andere Variable zu sehen, ohne dieser Variablen einen neuen Wert zuzuweisen. Wenn Sie dagegen ein Feld in einem Objekt ändern, werden alle Variablen, die auf dieses Objekt zeigen, diese Änderung sehen.

Lassen Sie uns einige Beispiele sehen:

var a = 1; 
var b = a; //This creates a new copy of value 1 
console.log(a, b); // 1 1 
a = 2; 
console.log(a, b); // 2 1 


var obj_a = {attr: 1}; 
var obj_b = obj_a; //This makes a new reference to the same object. 
console.log(obj_a, obj_b); // {'attr': 1} {'attr': 1} 
obj_b.attr = 2; 
console.log(obj_a, obj_b); // {'attr': 2} {'attr': 2} 

Unveränderliche Objekte: immutable.js

Bibliotheken wie immutable.js Arten liefern, die Eigenschaften von primitiven Typen und Objekte kombinieren: Typen von immutable.js verhalten als normale Objekte, solange Sie sie nicht ändern. Wenn Sie eine Eigenschaft eines unveränderlichen Objekts ändern, wird ein neues Objekt erstellt, und die Änderung ist nur durch dieses neue Objekt sichtbar. Der Vorteil ist, dass Sie Speicherplatz im Speicher sparen und die Gleichheit von Objekten schnell überprüfen können, indem Sie einfach nur ihre Referenzen vergleichen. Sie erhalten eine Reihe von Typen, die sich wie Ganzzahlen verhalten, aber Sie können komplexere Strukturen darin speichern.

+1

Pass by Referenz und Verwendung von Referenzen für Objekte ist ** nicht ** die gleiche Sache. JavaScript ist ein pass-by-Wert, und im Falle von Objekten ist der Wert eine Referenz. Sie verwirren, wie ** Werte ** mit der Auswertung von Variablen und Parametern dargestellt werden. Das sind zwei verschiedene Dinge. –

+0

es ist nicht wahr zu sagen, dass Strings immer nach Wert übergeben und daher kopiert werden. Strings werden eigentlich immer durch eine Referenz übergeben. –

+0

@MarcinMalinowski: siehe meinen vorherigen Kommentar. JavaScript ist pass-by-value, dieser Wert kann eine Referenz sein. Das Schöne an unveränderlichen Werten ist, dass sie kopiert oder referenziert werden können. Die Implementierung kann tun, was sie will. –

0

Mutation ist eine Zustandsänderung, während Zahlen (der primitive Typ) reine Zustandsobjekte sind. Jede Mutation zu einem solchen "Objekt" -Zustand ist tatsächlich eine neue Zahl. Die Zahl selbst ist wie eine Kennung für eine Mutation von Bits in einer Zelle des Computerspeichers.

Daher sind die Nummern nicht änderbar. Gleich wie Farben oder Zeichen.

Es ist auch wert, dass eine neue Nummer die selbe Speicherzelle wie die alte für jede gegebene Variable belegt. Eigentlich den alten ersetzen. Daher gibt es keinerlei Leistungseinbußen.

+0

Was meinst du mit "reinen Staatsobjekten"? – Jamo

+0

Wenn man versuchen würde, einen primitiven Wert als ein Objekt zu beschreiben, würde dieses Objekt keine Methoden haben, und das Objekt selbst würde, wenn es im Ausdruck verwendet wird, seinen Zustand als einzigen Wert auswerten. –

3

Ich bin ehrlich gesagt nicht ganz sicher, welche Art von Antwort Sie erwarten, da ich nicht ganz verstehe, worüber Sie verwirrt sind. Aber hier gehen wir:

Hätten wir 100 mal eine neue Referenz in der folgenden Schleife?

Variablen sind nur Container für Werte. Auf einer niedrigen Ebene ist eine Variable im Grunde nur eine Bezeichnung für eine Speicheradresse oder ein Register. Z.B. Variable x könnte auf Register R1 zeigen.

x++ würde einfach die Zahl erhöhen, die in diesem Register von 1 gespeichert wird. Nehmen wir an, unser Register sah wie folgt aus:

R1: 5 

Nach dem Erhöhen, die eine einzelne Operation sein kann, wie ADD R1 1, würden wir

R1: 6 

bekommen D.h. Wir überschreiben einfach den vorherigen Wert mit einem neuen Wert. Und wir machen das mehrfach.


Ist das leistungsfähig? Ich denke, ich sehe nicht richtig.

Das Erhöhen einer Zahl um eins ist so einfach wie möglich.

Sicher, könnten Sie änderbare Zahlen auf einer höheren Ebene implementieren, aber es würde sicherlich nicht die Dinge effizienter oder einfacher machen.

Für "Einzelwert" -Werte ist die Mutabilität nicht sehr sinnvoll, da das Mutieren eines solchen Wertes grundsätzlich bedeutet, dass er durch einen anderen Wert "in Place" ersetzt wird.

Änderbarkeit ist sinnvoller für Werte, die aus anderen Werten wie Listen und Wörterbüchern bestehen, wobei sich ein Teil ändert und der andere unverändert bleibt.

Außerdem scheint die Änderbarkeit nur relevant zu sein, wenn eine Sprache Referenztypen Datentypen hat. Damit meine ich, dass mehrere Variablen einen Verweis auf den gleichen Wert eines Datentyps enthalten können. Objekte sind Referenz-Typ in JavaScript, die Sie dies tun kann:

var a = {foo: 42}; 
 
var b = a; 
 
b.foo = 21; 
 
console.log(a);

Wenn Datentypen sind nicht von einem Referenztyp, die so genannten Value-Typ, (die primitiven Werte sind in JavaScript), dann ist die Veränderlichkeit nicht von Bedeutung, da sie von der Unveränderlichkeit nicht zu unterscheiden wäre. Betrachten Sie das folgende hypothetische Szenario mit einer wandelbaren, Wert-Typ-Nummer:

var a = MutableNumber(42); 
var b = a; // creates a copy of MutableNumber(42) because it's a value type 
a.add(1); 
console.log(a, b); // would log 43, 42 

In diesem Szenario ist es nicht möglich, dass zwei Variablen auf die gleiche veränderbare Zahlenwert zu verweisen, ist a.add(1) nicht von einem neuen Wert zu a zuweisen (dh a = a + 1).

+0

Das ist eine gute Antwort –

+0

Also, können wir sagen, dass Zahlen unveränderlich sind, weil jede Variable (Container) eine andere Referenz hat? Die Nummer kann nicht durch Referenz geändert werden. – Jamo

Verwandte Themen