Warum ist die Unveränderlichkeit so wichtig (oder nötig) in JavaScript?
Derzeit arbeite ich an Reagieren JS und Reagieren Nativen frameworks. Auf dem halben Weg stieß ich auf Unveränderlichkeit oder die Unveränderlich JS-Bibliothek, als ich war das Lesen über Facebook Flux und Redux Umsetzung.
Die Frage ist, warum ist die Unveränderlichkeit so wichtig? Was ist falsch in mutierend Objekte? Macht es nicht Dinge einfach?
Geben ein Beispiel, betrachten wir ein einfaches News-reader app mit der Eröffnung Bildschirm wird eine Listenansicht der news-Schlagzeilen.
Wenn ich sagen, ein array von Objekten mit einem Wert zunächst kann ich nicht manipulieren. Das ist es, was Unveränderlichkeit Prinzip sagt, richtig? (Korrigiert mich, wenn ich falsch bin.)
Aber was ist, wenn ich ein neues News-Objekt, das aktualisiert werden? Im üblichen Fall, ich hätte soeben das Objekt in das array.
Wie kann ich erreichen, in diesem Fall? Löschen, speichern und neu erstellen?
Nicht hinzufügen, ein Objekt in das array eine weniger teure operation?
PS: Falls das Beispiel ist nicht der richtige Weg, um zu erklären, Unveränderlichkeit, bitte lassen Sie mich wissen, was ist die richtige Praxis-Beispiel.
Relevant: programmers.stackexchange.com/questions/151733/...
Unveränderliche Daten Struktur und pure Funktion zu führen, um die referenzielle Transparenz, so dass es viel einfacher zu Grund, über das Verhalten Ihres Programms. Sie erhalten auch backtracking frei, wenn mit Hilfe der funktionellen Datenstruktur.
Habe ich eine Redux Sicht @bozzmob.
InformationsquelleAutor bozzmob | 2015-12-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe vor kurzem seit Jahren das gleiche Thema. Ich werde mein bestes tun, um Ihre Frage zu beantworten(s) und versuchen zu teilen, was ich bisher gelernt habe.
Grundsätzlich kommt es auf die Tatsache, dass der Unveränderlichkeit erhöht die Vorhersehbarkeit, die Leistung (indirekt) und ermöglicht eine mutation tracking.
Berechenbarkeit
Mutation verbirgt sich ändern, die (unerwartete) Nebenwirkungen, die dazu führen können böse Fehler. Wenn Sie erzwingen, Unveränderlichkeit, können Sie halten Sie Ihre Anwendung, Architektur und mentale Modell möglichst einfach zu halten, was es leichter macht, an die Vernunft zu Ihrer Anwendung.
Leistung
Obwohl hinzufügen von Werten zu einer immutable-Objekt bedeutet, dass eine neue Instanz erstellt werden muss, in denen bestehende Werte kopiert werden müssen und neue Werte Hinzugefügt werden müssen, um das neue Objekt, das kostet Speicher, unveränderliche Objekte können Gebrauch machen von strukturellen teilen des Speichers zu reduzieren overhead.
Lesen Sie mehr über dieses hier.
Mutation Tracking
Neben geringerem Speicherverbrauch, Unveränderlichkeit ermöglicht Ihnen die Optimierung Ihrer Anwendung durch die Verwendung von Referenz - und Wert-Gleichheit. Dies macht es wirklich einfach, um zu sehen, ob sich irgendwas geändert hat. Zum Beispiel kann ein Zustandswechsel in einen reagieren Komponente. Sie können
shouldComponentUpdate
um zu überprüfen, ob der Zustand identisch ist, durch den Vergleich von state-Objekten und verhindern unnötige Rendern.Lesen Sie mehr über dieses hier.
Zusätzliche Ressourcen:
Ja, das ist richtig. Wenn Sie verwirrt sind, wie zum implementieren dieser in Ihrer Anwendung würde ich dir empfehlen zu schauen, wie redux tut dies, um zu machen Sie sich vertraut mit den grundlegenden Konzepte, es hat mir sehr geholfen.
Benutze ich gerne wiedermal so ein Beispiel, weil es umarmt Unveränderlichkeit. Es hat einen einzigen unveränderlichen Zustand Baum (bezeichnet als
store
), wo alle Zustandsänderungen werden explizit durch die Entsendung von Aktionen, die verarbeitet werden, durch einen Druckminderer, der akzeptiert den vorherigen Zustand zusammen mit den genannten Aktionen (eins zu einem Zeitpunkt) und gibt den nächsten Zustand der Anwendung. Lesen Sie mehr über die Grundprinzipien hier.Es ist eine ausgezeichnete redux natürlich auf eierkopf.io wo Dan Abramov, der Autor von redux, erklärt diese Prinzipien wie folgt (ich veränderte den code ein wenig besser zu passen Szenario):
Ebenfalls diese videos zeigen im detail weiter, wie Sie zu erreichen Unveränderlichkeit für:
Sie sind herzlich willkommen! Nein, dass ist nicht richtig, Sie brauchen zur Durchsetzung der Unveränderlichkeit der Druckminderer selbst. Das heißt, Sie können die Strategien, wie gezeigt, in den videos oder benutzen Sie eine Bibliothek wie immutablejs. Finden Sie mehr info hier und hier.
ES6
const
ist nicht über die Unveränderlichkeit. Mathias Bynens schrieb eine große blog Artikel über.vielen Dank für den link. Ich Stimme zu, es ist eine wichtige Unterscheidung. ^_^
Bitte erklären Sie diese "Mutation verbirgt sich ändern, die (unerwartete) Nebenwirkungen, die dazu führen können böse Fehler. Wenn Sie erzwingen, Unveränderlichkeit, können Sie halten Sie Ihre Anwendung, Architektur und mentale Modell möglichst einfach zu halten, was es leichter macht, an die Vernunft zu Ihrer Anwendung." Da dies nicht auf alle im Zusammenhang mit JavaScript.
InformationsquelleAutor danillouz
Eine Konträre Ansicht von der Unveränderlichkeit
Kurze Antwort: Unveränderlichkeit ist mehr ein trend als eine Notwendigkeit in JavaScript. Es gibt ein paar schmale Fällen, wenn es sinnvoll wird (Reagieren/Redux meistens), obwohl in der Regel aus den falschen Gründen.
Lange Antwort: Lesen Sie unten.
Gut, ich bin froh, dass Sie gefragt!
Vor einiger Zeit ein sehr talentierter Kerl namens Dan Abramov ein javascript geschrieben, state-management-Bibliothek namens Redux, die verwendet reinen Funktionen und der Unveränderlichkeit. Er machte auch einige wirklich Coole videos, dass aus der Idee wirklich einfach zu verstehen (und zu verkaufen).
Das timing war perfekt. Die Neuheit von Eckige schwand, und die JavaScript-Welt bereit war, zu fixieren, auf der die Letzte Sache, hatte das richtige Maß von cool, und diese Bibliothek war nicht nur innovativ, sondern Schlitz-perfekt mit Reagieren das wurde mit von einem anderen Silicon-Valley-Kraftpaket.
Traurig, wie es sein kann, Mode-Regel in der Welt von JavaScript. Jetzt Abramov wird gefeiert wie ein Halbgott und alle uns sterblichen zu Unterwerfen uns die Dao-von der Unveränderlichkeit... Ob es Sinn macht oder nicht.
Nichts!
In der Tat-Programmierer mutiert Objekte für äh... wie lange hat es Objekte zu mutieren. 50+ Jahre Anwendungsentwicklung in anderen Worten.
Und warum die Dinge zu komplizieren? Wenn Sie object
cat
und es stirbt, tun Sie wirklich brauchen eine zweitecat
verfolgen das ändern? Die meisten Leute würden nur sagencat.isDead = true
und mit ihm getan werden.JA! .. Natürlich tut Sie das!
Speziell in JavaScript, die in der Praxis äußerst nützlich ist verwendet für das Rendern einer Ansicht mancher Staat, der anderswo (wie in einer Datenbank).
Gut, Sie können gehen den traditionellen Ansatz, und aktualisieren Sie die
News
Objekt, also Ihre in-memory-Repräsentation des Objekts ändert (und die Ansicht für den Benutzer angezeigt, oder, so würde man hoffen)...Oder alternativ...
Können Sie versuchen, die sexy FP/Unveränderlichkeit Ansatz und fügen Sie Ihre änderungen an der
News
Objekt in ein array tracking jede historische Veränderung so kann man dann das array Durchlaufen und herauszufinden, was die richtige staatlicher Repräsentation werden sollte (Puh!).Moden kommen und gehen, Kumpel. Es gibt viele Möglichkeiten, um der Haut eine Katze.
Tut mir Leid, dass Sie zu tragen haben, die Verwirrung, die von einer sich ständig verändernden Reihe von Programmier-Paradigmen. Aber hey, WILLKOMMEN im CLUB!!
Nun ein paar wichtige Punkte zu beachten, mit Bezug auf Unveränderbarkeit, und erhalten Sie diese auf Sie geworfen mit der fiebrigen Intensität, die nur die Naivität aufbringen können.
1) Unveränderlichkeit ist genial für die Vermeidung race conditions in multithreaded-Umgebungen.
Multi-threaded-Umgebungen (z.B. C++, Java und C#) sind schuldig an der Praxis von locking-Objekten, wenn mehr als ein thread ändern möchte. Das ist schlecht für die performance, aber besser als die alternative, Beschädigung von Daten. Und doch nicht so gut wie die alles unveränderlich (Herrn loben Haskell!).
ABER LEIDER!!!! In JavaScript ist es immer arbeiten in einem einzigen thread. Auch web workers (jeder läuft in einem separaten Kontext). Also da kann man nicht thread im Zusammenhang race-Bedingung in Ihrem Ausführungskontext (all die schönen Globale Variablen und-Verschlüsse), der wichtigste Punkt zugunsten der Unveränderlichkeit geht aus dem Fenster.
(Having said, die, es ist ein Vorteil der Verwendung von reinen Funktionen in web-worker, die ist, dass Sie keine Erwartungen an das hantieren mit Objekten auf der Haupt-thread.)
2) Unveränderlichkeit kann (irgendwie) Vermeidung von race-conditions in den Zustand Ihrer app.
Und hier ist die eigentliche Krux an der Sache, die meisten (Reagieren) - Entwickler wird Ihnen sagen, dass der Unveränderlichkeit und FP kann irgendwie funktioniert diese Magie, die ermöglicht, den Zustand Ihrer Anwendung zu vorhersehbar werden.
Natürlich bedeutet dies nicht, dass können Sie vermeiden, race-Bedingungen in der Datenbank zu ziehen, dass man aus müssten Sie koordinieren alle Benutzer in allen Browsern, und dafür brauchen Sie einen back-end-push-Technologie wie WebSockets (mehr dazu weiter unten) , wird die Sendung verpasst, jeder, der die app ausführt.
Diese eher verwirrend behaupten, bedeutet einfach, dass die aktuellen Werte zugeordnet, um ein state-Objekt (definiert durch einen einzelnen Benutzer in Ihren browser) vorhersehbar werden. Das ist wirklich gar kein Fortschritt. Da könnten Sie verwendet haben, ein einfaches, altes mutierte variable zu verfolgen, Ihr Zustand und Sie würden wissen, dass Sie den Umgang mit den neuesten Informationen, wenn Sie Zugriff haben, und diese Arbeit wird mit nichts, aber Reagieren/Redux.
Warum? Da Reagieren, ist Besondere.. und Komponente Staat verwaltet über eine Kette von Ereignissen, die Sie haben keine Kontrolle über und verlassen Sie sich auf Sie erinnern, nicht zu mutieren Stand direkt. Dieser behandelt wurde erstaunlicherweise von einer PR-Perspektive, wie die Reagieren hype hat sich ein Manko in einem sexy Weise. Mode beiseite, ich würde lieber sehen, Unveränderlichkeit, was es ist, sprich ein tool, schließen Sie eine Lücke, wenn Sie Ihre Wahl des Rahmens nicht handle state intuitiv.
3) Race-conditions sind grundsätzlich schlecht.
Gut, Sie könnten, wenn Sie mit Reagieren. Aber Sie sind selten, wenn Sie abholen einen anderen Rahmen.
Außerdem haben Sie normalerweise weit größere Probleme Umgang mit... Probleme wie Abhängigkeit Hölle. Wie ein aufgeblähter code-Basis. Wie Ihr CSS nicht immer geladen. Wie eine langsame build-Prozess oder sein fest zu einem monolithischen back-end, die macht der Iteration fast unmöglich. Wie unerfahrene Entwickler nicht verstehen, was Los ist, und machen ein Durcheinander von Dingen.
Wissen Sie. Realität. Aber hey, wen interessiert das?
4) Unveränderlichkeit nutzt Referenz-Typen zu reduzieren, die performance-Auswirkungen von tracking-jeder Zustand zu ändern.
Weil im ernst, wenn Sie gehen, um zu kopieren stuff jedes mal, wenn sich der Zustand ändert, Sie besser sicherstellen, dass Sie sind intelligent.
5) Unveränderlichkeit ermöglicht es Ihnen, RÜCKGÄNGIG Zeug.
Weil äh.. das ist die Nummer eins Ihrer Projekt-manager wird Sie bitten, richtig?
6) Unveränderlich Staat hat viele Coole Potenzial in Kombination mit WebSockets
Nicht zuletzt die Anhäufung von Staat deltas macht einen ziemlich überzeugenden Fall in Kombination mit WebSockets, die es ermöglicht, eine einfache Verbrauch von Zustand als flow unveränderliche Ereignisse...
Einmal der Groschen fällt, auf diesem Konzept (Bundesstaat ein Fluss der Ereignisse - eher als eine grobe Reihe von Datensätzen, die dem aktuellen Ansicht), die unveränderliche Welt wird zu einem magischen Ort zu bewohnen. Ein land der Ereignis-bezogen Wunder und der Möglichkeit, dass Zeit transzendiert sich selbst. Und wenn alles richtig gemacht kann dies auf jeden Fall machen Echtzeit-apps easier zu erreichen, müssen Sie nur broadcast ist der Fluss der Ereignisse an alle interessierten, so können Sie bauen Ihre eigene Darstellung der Gegenwart und schreiben Sie Ihre eigenen änderungen in die kommunale fließen.
Aber irgendwann werden Sie aufwachen und erkennen, dass alle, die sich Wundern und Magie kommen nicht umsonst. Anders als Ihre eifrigen Kollegen, die Ihren Stakeholdern (ja, die Leute, die bezahlen Sie) kümmern sich wenig um Mode und eine Menge über das Geld, das Sie zahlen, um zu bauen ein Produkt, das Sie verkaufen können. Und die Quintessenz ist, dass seine schwieriger zu schreiben unveränderlich code und einfacher, es zu brechen, und es gibt wenig Sinn, eine unveränderliche front-end, wenn Sie nicht über ein back-end zu unterstützen. Wenn (und falls!) Sie schließlich überzeugen, Ihren Stakeholdern, dass Sie sollten veröffentlichen und konsumieren von Ereignissen über einen push-Technologie, wie WebSockets, finden Sie heraus, was ein Schmerz ist es zu Maßstab in der Produktion.
Nun für einige Ratschläge, sollten Sie sich entscheiden, es zu akzeptieren.
Wahl zu schreiben, mit JavaScript FP/Unveränderlichkeit ist auch eine Wahl, um Ihre Anwendung code-Basis, die größer, komplexer und schwerer zu verwalten. Ich würde stark behaupten für die Begrenzung dieses Ansatzes auf Ihrer Redux Reduzierstücke.. es sei denn, Sie wissen, was Sie tun. In anderen Worten: Nur Keep It Simple™. Sie werden besser in den meisten Fällen. Und wo Sie nicht sind, würde ich konzentrieren sich auf immer die Vorteile von unveränderlichen Daten fließt durch deine (ganze) app, anstatt bauen eine rein funktionelle front-end und rufen Sie die Sache erledigt.
Nun, wenn Sie Glück genug, um in der Lage sein, Entscheidungen zu treffen in Ihrer Arbeit, dann versuchen Sie und verwenden Sie Ihre Weisheit (oder auch nicht) und tun, was richtig ist, indem die person, die Sie bezahlen. Sie stützen diese auf Ihre Erfahrungen, auf Ihr Bauchgefühl oder was um Sie herum (zugegeben, wenn jeder mit Reagieren/Redux dann gibt es ein argument, dass es leichter sein wird, um eine Ressource mit Ihrer Arbeit weitermachen).. Alternativ Sie können entweder versuchen, Lebenslauf Driven Development oder Hype-Driven Development Ansätze. Sie könnten mehr Ihre Art der Sache.
Kurz gesagt, das Ding zu sagen für die Unveränderlichkeit ist, dass es wird machen Sie modisch mit Ihren Kollegen, zumindest bis der nächste Schrei kommt herum, von welcher Stelle werden Sie froh sein zu bewegen auf.
Habe ich jetzt Hinzugefügt, dies als einen Artikel in meinem blog => Unveränderlichkeit in JavaScript: Eine Konträre Ansicht. Fühlen Sie sich frei, zu Antworten, wenn Sie starke Gefühle haben, die Sie gerne loswerden ;).
Ich habe mit Reagieren mit Flux/Redux seit über zwei Jahren und ich könnte nicht mehr Zustimmen mit Ihnen, tolle Antwort!
Ich bin sehr misstrauisch, dass die Ansichten auf Unveränderlichkeit korrelieren ziemlich sauber, team-und codebase-Größen, und ich glaube nicht, dass es irgendein Zufall, dass die Hauptbefürworter ist ein silicon-valley-Riesen. That being said, habe ich respektvoll widersprechen: Unveränderlichkeit ist eine nützliche Disziplin sein mag, nicht mit goto ist eine nützliche Disziplin. Oder unit-testing. Oder TDD. Oder statische Typ-Analyse. Bedeutet nicht, dass Sie tun, Sie die ganze Zeit, jedes mal, (obwohl einige tun). Ich würde auch sagen, dass Dienstprogramm orthogonal zum hype: in einer matrix nützlich/überflüssig und sexy/langweilig es gibt viele Beispiele von jedem.
"hyped" !== "bad"
Hi @ftor, guter Punkt, die Dinge nicht zu weit in die andere Richtung. Aber da es so eine fülle von " pro-Unveränderlichkeit in javascript Artikel und Argumente gibt, die ich fühlte, ich brauchte, um die Dinge auszugleichen. Also Neulinge haben eine entgegengesetzte Sicht, um Ihnen zu helfen, ein Urteil so oder so.
Informativ und Brillant mit dem Titel. Bis ich fand diese Antwort, ich dachte ich war der einzige, der holding eine ähnliche Ansicht. Ich erkenne den Wert der Unveränderlichkeit, aber was mich stört ist, dass es sich so ein alle-anderen-Technik-Unterdrückung dogma (z.B. zum Nachteil des 2-Wege-Bindung, die ist wahnsinnig nützlich für die Eingabe der Formatierung umgesetzt, in KnockoutJS zum Beispiel).
InformationsquelleAutor Steven de Salas
Eigentlich ist das Gegenteil wahr: seine Wandlungsfähigkeit macht die Dinge komplizierter, zumindest auf lange Sicht. Ja, es macht Ihrer anfänglichen Codierung einfacher, denn man kann nur Dinge ändern, wo immer Sie wollen, aber wenn dein Programm größer wird es ein problem – wenn Sie einen Wert geändert, was hat sich verändert?
Wenn Sie alles, was unveränderlich, bedeutet es, dass Daten nicht geändert werden können durch überraschung mehr. Sie wissen sicher, dass, wenn Sie übergeben einen Wert in eine Funktion, die nicht geändert werden kann in dieser Funktion.
Einfach ausgedrückt: wenn Sie unveränderliche Werte, es macht es sehr einfach, den Grund über Ihren code ein: jeder bekommt einen eindeutigen* - Kopie Ihrer Daten, so kann es nicht futz mit ihm und brechen andere Teile des Codes. Sich vorstellen, wie viel einfacher dies macht die Zusammenarbeit in einer multi-threaded Umgebung!
Hinweis 1: Es ist ein potenzielles Leistung Kosten auf Unveränderlichkeit je nachdem, was Sie tun, aber Dinge wie Immutable.js optimieren Sie so gut Sie können.
Hinweis 2: In dem unwahrscheinlichen Fall, Sie waren nicht sicher, Immutable.js und ES6
const
bedeuten sehr verschiedene Dinge.Ja, Ihre news-Beispiel ist vollkommen gut, und deine Argumentation ist genau richtig: man kann nicht einfach ändern Sie Ihre bestehenden Liste, so dass Sie brauchen, um eine neue zu erstellen:
OK; ich werde versuchen Sie zu Bearbeiten.
Ich bin froh, dass die Antwort hilfreich war! Bezüglich deiner neuen Frage: versuchen Sie nicht, heraus-denke, das system 🙂 In diesem genauen Fall, sowas nennt sich "structural sharing" reduziert GC Prügel dramatisch – wenn Sie über 10.000 Artikel in eine Liste, und fügen Sie 10 mehr, glaube ich Immutable.js werde versuchen die Weiterverwendung der bisherigen Struktur so gut er kann. Lassen Immutable.js sorgen über das Gedächtnis und die Chancen sind, Sie finden es kommt besser hin.
Imagine how much easier this makes working in a multi-threaded environment!
-> Ok, für die anderen Sprachen, aber dies ist nicht von Vorteil in single-threaded-JavaScript.immer noch mein Punkt bleibt. FP und Unveränderlichkeit sind mächtige nützliche Paradigmen zu vermeiden, die zur Beschädigung von Daten und/oder Ressourcen sperren in Multithread-Umgebungen, aber nicht so in JavaScript, denn Ihre single-threaded. Es sei denn, ich bin fehlen einige Heilige nugget der Weisheit der Haupt-trade-off ist hier, ob Sie bereit sind, machen Sie den code komplexer (und langsamer) in einer quest, um Wettlaufsituationen zu vermeiden ... die sind weit weniger ein Problem als die meisten Leute denken.
InformationsquelleAutor TwoStraws
Obwohl die anderen Antworten sind gut, um Ihre Frage zu einem praktischen Anwendungsfall (aus den Kommentaren auf die anderen Antworten), können Sie Schritt außerhalb Ihrer Laufenden code für eine minute und Blick auf die allgegenwärtige Antwort direkt unter deiner Nase: git. Was würde passieren, wenn jedes mal, wenn Sie gedrückt Begehen Sie überschrieben die Daten in das repository?
Nun sind wir zu einem der Probleme, die unveränderlichen collections Gesicht: Speicher aufblasen. Git ist clever genug, um nicht einfach machen, neue Kopien der Dateien, die jedes mal, wenn Sie eine änderung vornehmen, es einfach verfolgt die diffs.
Während ich don T wissen viel über das Innenleben von git, ich kann nur annehmen, dass es verwendet eine ähnliche Strategie, die von Bibliotheken Referenz: Struktur-sharing. Unter der Haube der Bibliotheken verwenden versucht oder andere Bäume, um nur verfolgen die Knoten, die anders sind.
Diese Strategie ist auch einigermaßen performante in-memory-Daten-Strukturen, wie es bekannt Baum-Betrieb-algorithmen, die den Betrieb in logarithmischer Zeit.
Anderen use-case: sagen Sie, Sie wollen eine undo-Taste auf Ihrer webapp. Unveränderliche Darstellungen Ihrer Daten, Implementierung eines solchen ist relativ trivial. Aber wenn Sie sich darauf verlassen, mutation, das bedeutet, dass man Angst haben muss das caching der Zustand der Welt und machen Atomare updates.
Kurz gesagt, es gibt einen Preis zu zahlen, für die Unveränderlichkeit in runtime-Leistung und die Lernkurve. Aber jeder erfahrene Programmierer wird dir sagen, dass das debugging Zeit überwiegt code-schreiben-Zeit um ein Vielfaches. Und die leichte Treffer auf die Laufzeit-performance ist wahrscheinlich überkompensiert durch die state-bezogene bugs Sie Ihre Nutzer nicht zu ertragen haben.
Nur weil ein Muster sinnvoll in git bedeutet nicht gleich Sinn macht, überall. In git Sie tatsächlich kümmern allen Geschichte gespeichert, und Sie möchten in der Lage sein zu verschmelzen verschiedener Branchen. Im frontend-Sie kümmern sich nicht darum, die meisten des Staates, der Geschichte und Sie brauchen nicht alle diese Komplexität.
es ist nur komplexer, weil es nicht der Standard. Ich normalerweise nicht verwenden, mori oder immutable.js in meinen Projekten: ich bin immer zurückhaltend auf third-party-Abhängigkeiten. Aber wenn das der Standard (a la clojurescript) oder hatten zumindest eine opt-in-native-option, ich würde es nutzen alle die Zeit, weil wenn ich z.B. Programmieren in clojure ich nicht sofort Sachen alles in Atome.
InformationsquelleAutor Jared Smith
Unveränderlichkeit verfolgt werden können, in verschiedenen Kontexten, aber am wichtigsten wäre es zu verfolgen, die gegen die Anwendung Staates und gegen die Anwendung UI.
Werde ich mich den JavaScript-Redux-Muster sehr trendy und modernen Ansatz und weil Sie erwähnt.
Für die Benutzeroberfläche, die wir brauchen, um es vorhersehbar.
Es wird vorhersagbar ist, wenn
UI = f(application state)
.Anwendungen (in JavaScript) ändert der Staat durch Maßnahmen, die mithilfe der reducer-Funktion.
Die reducer-Funktion nimmt einfach die action und den alten Zustand und liefert den neuen Zustand, halten Sie die alt-Zustand intakt.
Vorteil ist: Sie haben Zeit-Reise-die Staaten da alle state-Objekte werden gespeichert, und Sie können machen die app in jedem Staat seit
UI = f(state)
So können Sie undo/redo leicht.
Passiert, zu erstellen alle diese Zustände können noch Speicher effizient, der einen Vergleich mit Git ist Super, und wir haben das ähnliche Analogie in der Linux-OS mit symbolischen links (basierend auf den inodes).
InformationsquelleAutor prosti
Über die Veränderlichkeit
Nichts falsch Veränderlichkeit aus technischer Sicht. Es ist schnell, es ist wieder mit dem Speicher. Die Entwickler verwenden, um es von Anfang an (als ich es in Erinnerung habe). Problem besteht in der Verwendung von Veränderlichkeit und Probleme, die dieser Einsatz mit sich bringen kann.
Wenn das Objekt nicht freigegeben ist, mit etwas, zum Beispiel existiert in dem Gültigkeitsbereich der Funktion und nicht der Außenwelt ausgesetzt, dann ist es schwer, Vorteile zu sehen, in der Unveränderlichkeit. Eigentlich ist es in diesem Fall keinen Sinn, die unveränderlich sind. Das Gefühl der Unveränderbarkeit beginnt, wenn etwas geteilt wird.
Veränderlichkeit Kopfschmerzen
Veränderlich gemeinsame Struktur können sehr einfach viele Fallstricke. Jede Veränderung in jedem Teil des Codes mit Zugang zum Verweis hat Auswirkungen auf andere Teile, mit Sichtweiten von dieser Referenz. Solche Auswirkungen verbindet alle Teile zusammen, auch wenn Sie nicht sollten sich der unterschiedlichen Module. Mutation in einer Funktion kann zum Absturz ganz anderen Teil der app. So etwas ist eine schlechte Nebenwirkung.
Nächsten oft problem mit mutation beschädigten Zustand. Beschädigten Zustand passieren kann, wenn die mutation Verfahrens nicht in der Mitte, und einige Felder wurden geändert und einige nicht.
Was mehr ist, mit der mutation, ist es schwer zu verfolgen, das zu ändern. Einfache überprüfung der Referenzen nicht zeigen, wird der Unterschied, zu wissen, was sich verändert hat, einige deep-check gemacht werden muss. Auch zum überwachen von änderungen einige erkennbare Muster muss eingeführt werden.
Schließlich, mutation ist auf Grund der Vertrauens-Defizit. Wie können Sie sicher sein, dass eine gewisse Struktur hat, wollte Wert, wenn es mutiert ist.
Als obige Beispiel zeigt, vorbei veränderliche Struktur immer beenden können, indem er andere Struktur. Funktion doSomething mutiert das Attribut von außerhalb. Kein Vertrauen für den code, die Sie wirklich nicht wissen, was Sie haben und was Sie haben. All diese Probleme stattfinden, denn: Veränderliche Strukturen repräsentieren-Zeiger auf den Speicher.
Unveränderbarkeit wird über Werte
Unveränderbarkeit bedeutet, dass die änderungen nicht gemacht, die auf das gleiche Objekt,Struktur, sondern ändern Sie vertreten im neuen. Und das ist, weil die Referenz repräsentiert den Wert nicht nur den Speicher-Zeiger. Jede Veränderung schafft neue Werte und berührt nicht den alten. Solche klaren Regeln gibt wieder das Vertrauen und den code Berechenbarkeit. Funktionen sind sicher zu verwenden, weil statt der mutation, mit denen Sie umgehen, eigene Versionen mit eigenen Werten.
Mithilfe von Werten statt von Speicher-Container gibt die Gewissheit, dass jedes Objekt repräsentiert bestimmten unveränderlichen Wert, und es ist sicherer, es zu benutzen.
Unveränderliche Strukturen repräsentieren Werte.
Ich bin Tauchen noch mehr in das Thema im medium Artikel - https://medium.com/@macsikora/the-state-of-immutability-169d2cd11310
InformationsquelleAutor Maciej Sikora
Weiterer Vorteil der Unveränderlichkeit in Javascript ist, dass es reduziert die Zeitliche Kopplung, die erhebliche Vorteile für design im Allgemeinen. Betrachten Sie die Schnittstelle ein Objekt mit zwei Methoden:
Kann es der Fall sein, dass ein Aufruf
baz()
ist erforderlich, um das Objekt in einem gültigen Zustand für einen Anruf zubar()
um korrekt zu arbeiten. Aber Woher weißt du das?Um es herauszufinden, müssen Sie die Prüfung der Klasse Interna, denn es ist nicht sofort ersichtlich, von der Prüfung der öffentlichen Schnittstelle. Dieses problem kann explodieren, in eine große Codebasis mit vielen änderbaren Zustand und Klassen.
Wenn
Foo
unveränderlich ist, dann ist dies kein problem mehr. Es ist sicher davon ausgehen, dass wir anrufen könnenbaz
oderbar
in beliebiger Reihenfolge, weil der innere Zustand der Klasse nicht ändern können.InformationsquelleAutor ghostypants
Ein Anderes Nehmen...
Meine andere Antwort behandelt die Frage von einem sehr praktischen Standpunkt aus, und ich mag es immer noch. Ich habe beschlossen, dies als eine andere Antwort eher als eine Ergänzung, weil es ist eine langweilige philosophische Tirade, die sich hoffentlich auch die Frage beantwortet, aber passt nicht wirklich mit meiner vorhandenen Antwort.
TL;DR
Selbst in kleinen Projekten Unveränderlichkeit nützlich sein kann, aber nicht annehmen, weil es existiert, es ist für Sie gedacht.
Viel, viel mehr beantworten
HINWEIS: für die Zwecke dieser Antwort, die ich mit dem Wort 'Disziplin' bedeutet Selbstverleugnung für einige Vorteile.
Dies ist ähnlich in der form zu einer anderen Frage: "Sollte ich verwenden Typescript? Warum sind Typen so wichtig in JavaScript?". Es hat eine ähnliche Antwort zu. Betrachten Sie das folgende Szenario:
So, jetzt haben Sie eine Wahl zu machen, Sie bewegen sich zu Typescript?
Typoskript hat einige überzeugende Vorteile: intellisense, fangen, Fehler frühzeitig, unter Angabe Ihrer APIs im Voraus, einfache Befestigung Dinge bei der Umgestaltung der Pausen, weniger tests. Typoskript hat auch einige Kosten: gewisse sehr Natürliche und korrekte JavaScript-Idiome kann schwierig sein, im Modell ist es nicht-besonders-leistungsfähiges Typ-system, Anmerkungen wachsen die LoC, die Zeit und den Aufwand umschreiben von bestehenden Codebasis zusätzlichen Schritt in die build-pipeline, etc. Mehr grundlegend, es bahnt sich eine Teilmenge mögliche korrekte JavaScript-Programme im Austausch für das Versprechen, dass Ihr code ist eher korrekt zu sein. Es ist willkürlich restriktiv. Das ist der springende Punkt: Sie verhängen einige Disziplin, die Grenzen, die Sie (hoffentlich von shooting selbst in den Fuß).
Zurück zu der Frage, also im Rahmen des vorstehenden Absatzes: ist es lohnt es?
In dem Szenario beschrieben, würde ich behaupten, dass wenn Sie sehr vertraut mit einem kleinen-zu-mittleren JS codebase, dass die Wahl zu verwenden, Maschinenschrift, mehr ästhetischen als praktischen. Und das ist feine, es gibt nichts falsch mit einer ästhetik, Sie sind gerade nicht unbedingt überzeugend.
Szenario B:
Zurück, wenn Sie waren 5k LoC Kerl/Mädchen, es hat einfach keine Rolle, dass viel. Auch die Dokumentation war nicht , dass große Sache, auch kommen zurück, um einen bestimmten Teil des Codes nach 6 Monaten konnten Sie es herausfinden leicht genug. Nun aber Disziplin ist nicht nur schön, sondern notwendig. Diese Disziplin kann nicht bedeuten, Typoskript, aber wird wahrscheinlich um eine form der statischen Analyse wie auch alle anderen Formen der Codierung Disziplin (Dokumentation, style guides, build-Skripte, regression-Tests, CI). Disziplin ist nicht mehr ein Luxus, es ist ein Notwendigkeit.
All dies angewandt, um
GOTO
1978: Ihrer hübschen kleinen blackjack-Spiel in C verwenden könnteGOTO
s und spaghetti Logik und es war einfach nicht, dass große einen deal zu wählen-Sie-Ihre-eigene-Abenteuer Ihren Weg durch es, aber wie die Programme grösser und anspruchsvoller, gut, undiszipliniert Verwendung vonGOTO
konnte nicht aufrechterhalten werden. Und all dies bezieht sich auf Unveränderlichkeit heute.Genauso wie statische Typen, wenn Sie nicht über eine große Codebasis mit einem team von Ingenieuren die Wartung/Erweiterung es ist die Wahl der Unveränderlichkeit ist mehr ästhetischen als praktischen: es ist Vorteile sind noch da können aber nicht die Kosten überwiegen noch.
Aber wie mit allen nützlichen Disziplinen, es kommt ein Punkt, an dem es nicht mehr optional. Wenn ich will, um ein gesundes Gewicht zu halten, dann Disziplin mit Eis optional sein. Aber wenn ich will ein Leistungssportler, meine Wahl, ob oder nicht, um Eis zu Essen subsumiert, die durch meine Wahl der Ziele. Wenn Sie möchten, ändern Sie die Welt mit software, Unveränderlichkeit, könnte ein Teil von dem, was Sie brauchen, um zu vermeiden, kollabiert unter dem eigenen Gewicht.
seine eine form von Disziplin. Und als solche, ich denke, es ist korreliert mit (aber nicht ersetzen) die anderen Formen der software-engineering-Disziplin. Sie ergänzt, statt verdrängt. Aber wie ich sagte in einem Kommentar auf deine Antwort, ich bin nicht überrascht, dass es ist seiend gestoßen von einem tech-Riese mit einer Schar von Ingenieuren, die alle Schleifen entfernt auf der gleichen riesigen Codebasis 🙂 Sie müssen alle die Disziplin, die Sie bekommen können. Ich zum größten Teil nicht mutieren die Objekte aber auch nicht jede form der Durchsetzung, da, gut, es ist nur mir.
InformationsquelleAutor Jared Smith
Once upon a time, gab es ein problem mit der Synchronisation zwischen threads. Dieses problem war ein großer Schmerz, da waren 10+ Lösungen. Einige Leute versucht, es zu lösen radikal. Es war ein Ort, wo die funktionale Programmierung war geboren. Es ist wie der Marxismus. Ich konnte nicht verstehen, wie Dan Abramov verkauft diese Idee in JS, denn es ist single-threaded. Er ist ein Genie.
Kann ich Ihnen ein kleines Beispiel. Es ist ein Attribut
__attribute__((pure))
im gcc. Compiler versucht zu lösen, ob Ihre Funktion ist rein oder nicht, wenn Sie nicht declear es speziell. Ihre Funktion kann rein auch Ihr Staat ist veränderlich. Unveränderlichkeit ist nur einer von 100+ Möglichkeiten, um zu garantieren, dass Sie funktionieren wird rein sein. Tatsächlich 95% der Funktionen werden rein.Sie sollten keine Einschränkungen (wie Unveränderbarkeit), wenn Sie eigentlich keinen ernsthaften Grund. Wenn Sie "Rückgängig" einige Zustand, können Sie Transaktionen erstellen. Wenn Sie möchten, vereinfachen die Kommunikation, die Sie senden können Veranstaltungen mit unveränderlichen Daten. Es ist bis zu Ihnen.
Ich Schreibe diese Nachricht von post-Marxismus Republik. Ich bin sicher, dass die Radikalisierung der Vorstellung einen falschen Weg.
InformationsquelleAutor puchu
Ich denke, der Hauptgrund pro unveränderliche Objekte, die den Zustand des Objekts gültig.
Nehmen wir an, wir haben ein Objekt namens
arr
. Dieses Objekt ist nur gültig, wenn alle Elemente den gleichen Brief.wenn
arr
zu einem unveränderlichen Objekt, dann werden wir sicher arr ist immer in einem gültigen Zustand befindet.arr
bekommt mutiert jedes mal, wenn Sie rufenfillWithZ
wenn Sie immutable.js Sie erhalten eine neue Kopie des Objekts, jedes mal, wenn Sie es ändern. also das ursprüngliche Objekt bleibt unverändert
InformationsquelleAutor bedorlan