Moment: Moment größtenteils unveränderlich machen

Erstellt am 3. Juli 2014  ·  163Kommentare  ·  Quelle: moment/moment

Darüber hat es viele Diskussionen gegeben . Hier der Vorschlag:

Die folgenden veränderlichen Methoden werden in 3.0.0 unveränderlich: utc , local , zone , add , subtract , startOf , endOf , lang , auch in duration : add , subtract und lang .

Zunächst werden alle Methoden mit methodNameMute Varianten dupliziert. Wir brauchen auch unveränderliche Varianten namens methodNameImmute . Ab 3.0 verwenden die einfachen alten Methoden standardmäßig die Option unveränderlich.

Umstritten ist:

  • sollte lang unveränderlich gemacht werden
  • sollten alle Getter/Setter (einschließlich get / set ) auch unveränderlich gemacht werden
  • Benennung der veränderlichen und unveränderlichen Versionen der Methoden
  • und natürlich – sollten wir den Wechsel vornehmen oder einfach bei der unveränderlichen API aufhören?

Das Gute daran ist, dass wir heute unveränderliche Versionen der Methoden erstellen und später entscheiden können, was zu tun ist. Wenn wir wechseln, würde dies auch bedeuten, dass der 2.x Zweig für einige Zeit verfügbar wäre, nachdem 3.x ist.

@icambron @timrwood @gregwebs @yang @lfnavess @soswow @langalex

Enhancement

Hilfreichster Kommentar

Meine zwei Cent sind, dass wir entweder auf absolute Unveränderlichkeit setzen sollten oder überhaupt nicht. Es ist einfach verwirrend, dass einige Methoden unveränderlich sind ( startOf , add ) und andere nicht ( year , get ), und Entwickler müssen den Überblick behalten welche sind welche.

Alle 163 Kommentare

Meine zwei Cent sind, dass wir entweder auf absolute Unveränderlichkeit setzen sollten oder überhaupt nicht. Es ist einfach verwirrend, dass einige Methoden unveränderlich sind ( startOf , add ) und andere nicht ( year , get ), und Entwickler müssen den Überblick behalten welche sind welche.

Ich würde auch bevorzugen, dass standardmäßig alles unveränderlich ist. Sind die Getter nicht schon unveränderlich?

Hier sind die großen Probleme, die ich beim Wechsel zur Unveränderlichkeit sehe.

Pseudo-Unveränderlichkeit

Aufgrund der Natur von Javascript werden wir niemals echte Unveränderlichkeit haben können.

Das Beste, was wir tun können, ist, eine Kopie zu erstellen, dann zu mutieren und diese Kopie zurückzugeben. Wir können alle öffentlichen Methoden sorgfältig umschließen, um sicherzustellen, dass wir immer kopieren und mutieren, anstatt nur zu mutieren, aber das hindert jemanden nicht daran, m._d = new Date() oder sogar m._d.setHours(1) tun.

Ich stimme @icambron zu , wenn wir zur Unveränderlichkeit

API-Oberfläche

Das Unglückliche beim Wechsel zur Pseudo-Unveränderlichkeit ist, dass viele neue APIs erstellt werden müssen, wenn wir die Veränderlichkeit weiterhin unterstützen wollen.

Zuvor war der Wechsel vom Mutieren eines Moments zum Klonen und Mutieren eines Moments so einfach wie das Hinzufügen eines .clone() an der richtigen Stelle. Jetzt müssten wir für alle Setter veränderbare Schnittstellen erstellen, was die API-Oberfläche erheblich vergrößert.

Dazu gehören die ~20 Setter-Methoden, add/subtract, local/utc/zone/tz, startOf/endOf, lang und alle anderen Methoden, die in Plugins von Drittanbietern verwendet werden.

Gedächtnisprobleme

Da wir jetzt jedes Mal Kopien erstellen, wenn wir einen Wert ändern möchten, erhöht sich der Speicherverbrauch. Natürlich werden die neuen Momente im Müll gesammelt, aber die zusätzlichen Kosten, die mit dieser Änderung verbunden sind, sollten Sie im Auge behalten.

Wir müssten sehr vorsichtig sein, um sicherzustellen, dass wir nicht mit Methoden, die andere Setter verwenden, Tonnen von Einwegklonen erstellen.

Um zu verfolgen, welche Methoden aufgerufen werden, habe ich diesen kleinen Funktionswrapper verwendet.

for (var method in moment.fn) {
  moment.fn[method] = (function (fn, method) {
    return function () {
      console.log(method);
      return fn.apply(this, arguments)
    }
  })(moment.fn[method], method)
}

Wenn wir nun eine Methode ausführen, können wir sehen, wie viele andere Methoden auf dem Prototyp verwendet werden. Nicht alle diese Methoden müssten momentan geklont werden, daher habe ich Kommentare zu denen hinzugefügt, die geklont werden müssen.

moment().isSame(moment(), 'year')
isSame
clone        // clone
startOf      // clone
month        // clone
date         // clone
year         // clone
date         // clone
hours        // clone
minutes      // clone
seconds      // clone
milliseconds // clone
valueOf
local        // clone
zone         // clone
startOf      // clone
month        // clone
date         // clone
year         // clone
date         // clone
hours        // clone
minutes      // clone
seconds      // clone
milliseconds // clone
valueOf

Das sind 21 Kopien, die erstellt und dann sofort verworfen werden. Offensichtlich könnten wir dies optimieren, indem wir einige interne Methoden verwenden, die veränderlich sind und nur die unveränderlichen Versionen verfügbar machen, aber es wird die interne Komplexität erheblich erhöhen, wenn wir versuchen, aufzuzeichnen, welche Momente noch geklont werden müssen und welche nicht.

Leistungsbedenken

Einen Moment zu klonen ist viel langsamer als einen Moment zu mutieren. Ich habe dafür ein paar Jsperf-Tests zusammengestellt.

http://jsperf.com/moment-klonen

http://jsperf.com/moment-cloning-2

Ich denke, der zweite Test ist eine viel bessere Darstellung der Leistungsverluste beim Umschalten auf Pseudo-Unveränderlichkeit. Wenn wir diese Ergebnisse mit den oben genannten 21 Kloninstanzen multiplizieren, sind die Ausführungszeiten viel langsamer.

Ich bin sicher, wir könnten den Pfad für das Klonen einen Moment optimieren, aber wir müssten ihn 50x schneller machen, um eine vergleichbare Leistung zu erzielen. Ich bin mir ziemlich sicher, dass das unmöglich ist.

Zusammenfassung

Das Umschalten auf Unveränderlichkeit erhöht die Komplexität der internen und externen APIs erheblich und bringt erhebliche Leistungs- und Speicherprobleme mit sich. Ich glaube nicht, dass diese Kosten die Vorteile wert sind, die die Unveränderlichkeit bieten würde.

Ich denke, die hier aufgeführten Leistungsbedenken verfehlen den Punkt:

Im Allgemeinen ist eine anfängliche .clone()-Datei erforderlich, um die Korrektheit sicherzustellen, bevor eine Mutation durchgeführt wird.

Wir können nicht so tun, als ob clone() mit der aktuellen API nicht benötigt wird. Der Hauptfall, der hier anders ist, ist die Durchführung mehrerer sequentieller Mutationen. Dieser Fall wird durch Erstellen einer Builder-API behandelt, sodass alle Mutationen als Mutationen auf einem einzigen Klon ausgeführt werden.

Übersehe ich andere häufige Anwendungsfälle?

Mein ursprüngliches Problem betraf speziell die Methoden startOf und endOf . Aus irgendeinem Grund waren diese Namen für mich wie "besorge mir einen Monatsbeginn" und nicht "diesen Moment auf den Beginn eines Monats setzen". Methoden wie add und subtract sind im Sinne der Semantik vollkommen in Ordnung. Es ist völlig in Ordnung, einem Objekt etwas hinzuzufügen, ohne ein neues zu erstellen.
Für mich persönlich würde die Umbenennung von Methoden startOf und endOf in etwas wie toStartOf und toEndOf (wie "Diesen Moment auf den Anfang eines Monats verschieben") das Problem lösen Ausgabe. meiner bescheidenen Meinung nach

@gregwebs Entschuldigung, ich meinte oben set .

Ich stimme @soswow nicht zu; Ich denke, es muss konsequent sein. Tatsächlich denke ich, dass toStartOf Unveränderlichkeit noch stärker impliziert, so wie es eine alternative Präsentation à la toISOString bietet. Noch wichtiger ist, dass wir in der Lage sein müssen, Aussagen wie "Moment-Setter mutieren Momente" oder "Moments-Setter geben Kopien zurück" zu machen, nicht "nun, für diese Methoden ..."

Zu @timrwoods Bedenken:

Dass die JS-Objekte nicht wirklich unveränderlich sind, stört mich nicht. Der Punkt ist, dass die API einen unveränderlichen Vertrag bereitstellt. Natürlich kann der Benutzer schummeln, indem er an den unterstrichenen Eigenschaften herumfummelt, und Schummeln ist im Allgemeinen sogar in Sprachen möglich, bei denen Unveränderlichkeit die Hauptmethode ist.

Zur Oberfläche und zur Leistungsfähigkeit: Ich denke, wir müssen die Mutatoren intern verwenden, um nicht all die CPU und den Speicher zu verbrauchen [1], also müssen wir sie dann auf einer gewissen Ebene unterstützen. Dann könnten wir sie genauso gut extern freigeben, wie setYear() usw. Das fügt eine Menge Oberfläche hinzu, aber es erhöht nicht wirklich viel Komplexität; für nicht-explizite Mutatoren extern klonen, intern mutieren.

Eine Möglichkeit, dies zu betrachten, besteht darin, dass der Benutzer seinen Code klonen muss, also könnte Moment genauso gut für ihn tun. Dies stellt ein Problem mit der Verkettung an leistungsempfindlichen Stellen dar, das entweder durch eine Builder-Schnittstelle (nach Gregs Idee) oder durch die Verwendung von Mutatoren dort bekämpft werden könnte. Der Builder fügt eine Menge Komplexität hinzu [2], daher bevorzuge ich einfach explizite Mutator-Alternativen. Ich denke, die Realität ist, dass Moment die meiste Zeit nicht in leistungsempfindlichen Situationen verwendet wird, daher müssen diese Situationen nicht die bequemste API-weise sein. Ich hätte lieber eine schöne unveränderliche API mit einer Perf-Schraffur, wenn ich sie brauche.

[1] Die coolen Kids im FP-Land lösen das mit _structural sharing_, aber das ist hier wahrscheinlich unpraktisch.

[2] Traditionell werden Builder erstellt, die separate Objekte sind, aber das wäre hier wirklich ausführlich, da Sie die gesamte Setter-API kopieren müssten. Nur spucken, aber eine Alternative ist, dass .chain() einen Klon-Moment erzeugt, auf dem nur ein isBuilding Flag gesetzt ist. Dann werden interne Klone ignoriert und nur das Objekt zur Mutation zurückgegeben. Dann entfernt build() das Flag und gibt diesen Klon zurück. Das Problem ist, dass Sie Ihre Getter brauchen, um blutigen Mord zu schreien, wenn die Flagge gesetzt ist, oder die Leute werden die verketteten, aber ungebauten Momente verwenden, die plötzlich mutatorisch sind. Dann müssen Sie extern und intern sogenannte Getter unterscheiden. Blech. Eine andere Alternative besteht darin, die vom Builder benötigte Funktionalität intern in ein Mixin zu zerlegen und sowohl im Builder als auch in Moment zu verwenden, aber das ist aus der Sicht der Codeorganisation wahrscheinlich nicht praktikabel.

Was für mich funktionierte, war das Hinzufügen eines zusätzlichen Parameters zu den Funktionen, ein Flag (ich nannte mich selbst), um die Veränderlichkeit anzuzeigen, ist standardmäßig in unveränderlich (eine Kopie oder ein neues Objekt zurückgeben), und wenn ich die Leistung erkenne, setze ich das Flag auf true

dieser Standpunkt löste viele Konflikte,
Funktionen mit ähnlichem Namen haben, die fast den gleichen Code ausführen,
oder ich muss den Funktionsnamen und wahrscheinlich die Parameter ändern, wenn ich Leistungspunkte erkenne
In meinen öffentlichen Methoden starte ich den Code, der die Funktionen aufruft, mit einer Kopie und folgenden Aufrufen mit dem Flag in true
damit kann ich auch die funktionen verketten

In meinem Code arbeite ich mit Arrays von Arrays (wie eine Tabelle, Array von Zeilen)
Also habe ich Funktionen zum Filtern, Vereinigung usw., die zuvor ein neues Array mit dem Ergebnis erneut ausführen, und ich erkenne, dass ich die gleiche Funktion mehrmals aufgerufen habe, um das Endergebnis zu erhalten. Jetzt besteht der erste Aufruf darin, eine Kopie zu erstellen und nicht zu ändern das anfängliche Array und die folgenden Aufrufe arbeite ich mit dem gleichen Array, das eine Zeile löscht, die ich nicht brauche

ein einfaches Beispiel, das hier sein könnte:
moment.add = Funktion (Maß, Betrag, Selbst){
}

moment.add = Funktion (Maß, Betrag, Selbst) {
var $moment = selbst ? this: this.clone();
// der eigentliche Code
kehre $moment zurück;
}

Danke an alle für ihre 2 Cent :)

Für das Protokoll stimme ich dem letzten Post von

Es bleiben zwei große Fragen.

Die einfachere ist, was die neue API sein sollte, zwei Optionen:
1.1 Methoden mit unterschiedlichen Namen (veränderbar und unveränderlich) year / setYear , startOf / setStartOf
1.2 oder Builder-API chain().mutators().build() , die nicht-hackige Version von dem, was @lfnavess vorgeschlagen hat.

Die Builder-API sieht definitiv sexier aus, aber es sollte darauf geachtet werden, dass Objekte nicht zu lange im Build-Modus bleiben, was für uns und die Benutzer eine weitere Ärgerquelle darstellt.

Jetzt das schwierige Problem - die Migration auf die neue Version. Ich sehe hier zwei Möglichkeiten:
2.1-Entwickler müssen ihren Code neu schreiben (verrückte Regex könnte in 1.1 und AST-Level-Lösung für 1.2 funktionieren – vorausgesetzt, niemand verwendet year und month als Namen seiner eigenen Methoden). Python verfolgte diesen Ansatz – wir können das Ergebnis alle sehen – eine brandneue Sprache war geboren!
2.2 Option, um die Builder-API immer zu aktivieren (wie jetzt) ​​und eine Möglichkeit, sie für neuen Code zu deaktivieren. Das sieht eher _evolutionär_ aus, aber die Menge an Verwirrung, die es verursachen würde, ist es wahrscheinlich nicht wert. Jeder Moment hat jetzt zwei Flags: ist er veränderbar, und falls ja, ist er streng veränderbar (keine Getter) oder vorübergehend veränderbar (Getter ok). Ganz zu schweigen vom Empfangen von Momentobjekten in Funktionen -- Sie sollten überprüfen, was der Modus ist, stellen Sie sicher, dass Sie ihn beibehalten ... was für ein Durcheinander!


Und jetzt kam mir jetzt eine verrückte Idee

Copy-on-write-Klon

m = moment();
funcIDontTrust(m.clone());  // doesn't actually clone

function funcIDontTrust(m) {
  m.year(2005);  // perform the clone here
  console.log(m);
}

Ich bin mir nicht sicher, wie viel mit diesem Ansatz eingespart werden kann, da die Instanzen im Moment ziemlich leicht sind. Auch alle Mutatoren müssen nun einen Check durchführen.

Es gibt einige Möglichkeiten, mit unterschiedlicher Leistung in verschiedenen Szenarien zu implementieren. Die gute Nachricht ist, dass es abwärtskompatibel ist und wir uns und unseren Benutzern viel Mühe ersparen. Und ich denke, das ist wichtiger, als das Rad neu zu erfinden.

Ich bin mir nicht sicher, was wir hier gewinnen.

Der Wechsel zu Unveränderlichkeit ist mit einer Menge Kosten verbunden und vielleicht übersehe ich sie, aber
Ich sehe keine vergleichbaren Vorteile.

Der Hauptvorteil scheint die Präferenz der Entwickler zu sein. Ist das alles so, dass Entwickler nicht haben?
über den Besitz eines Augenblicks nachdenken, wenn man ihn herumreicht?

Ich glaube nicht, dass der Wechsel zur Unveränderlichkeit die Häufigkeit von Fehlern verringert, sondern nur
Ändern Sie die Art der Fehler. Das Beispiel von
Oberfläche, die ebenso schwer aufzuspüren sind.

m = moment();
funcIDontTrust(m.clone());  // doesn't actually clone

function funcIDontTrust(m) {
  m.year(2005);  // perform the clone here
  // m is still in 2014
  // m.year(2005) created a clone but did not assign it to anything
  // it should be `m = m.year(2005)`
  console.log(m);
}

Hier ist eine Pro/Kontra-Liste zwischen Veränderlichkeit und Unveränderlichkeit. Wenn ich etwas verpasst habe,
lass es mich wissen und ich werde diesen Kommentar bearbeiten.

| Unveränderlich | änderbar |
| --- | --- |
| Einige Entwickler bevorzugen es | Einige andere Entwickler bevorzugen es |
| Vermeidet Bugs beim Herumgehen in Momenten | Vermeidet Fehler, wenn vergessen wird, geklonte Momente zuzuweisen |
| Mit einigen Dutzend neuer API-Methoden wird auch Mutability unterstützt | Mit der vorhandenen .clone()-Methode wird Unveränderlichkeit bereits unterstützt |
| | Eine Größenordnung schneller |
| | Verbraucht deutlich weniger Speicher |

Ich denke, dass Unveränderlichkeit nützlich ist, aber ich denke nicht, dass sie in JavaScript passt. Ich denke, eine unveränderliche Schnittstelle kann für eine Sprache wie Elm sinnvoll sein, in der Unveränderlichkeit erwartet wird, aber für JavaScript denke ich, dass Veränderlichkeit erwartet wird.

Viele der APIs für typeof a === "object" Built-Ins sind veränderbar. Array#push,pop,reverse,sort,shift,splice,unshift alle ändern den Inhalt eines Arrays, anstatt ein neues Array zurückzugeben. Alle 16 der Date#setX Methoden mutieren ihre Instanz.

Ich denke, wir sehen viele Leute, die sich darüber beschweren, dass Momente veränderlich sind, aber wenn wir wechseln, werden sich meiner Meinung nach genauso viele Leute beschweren. Dies hat bereits geschehen mit der eod/sod vor Methoden zwei Jahren.

Nachdem ich mir ein paar alte Probleme zur Veränderlichkeit angeschaut habe, klinge ich hier wahrscheinlich wie eine gebrochene Schallplatte. Auf beiden Seiten sind es die gleichen Punkte, die in den letzten Jahren angesprochen wurden. Ich wollte nur sicherstellen, dass ein Argument für die Beibehaltung einer veränderlichen API in der Diskussion vertreten ist.

@timrwood das sind gute Vergleiche, aber es ist ziemlich klar, dass Sie sich nicht die Zeit genommen haben, den unveränderlichen Anwendungsfall zu verstehen. Wir haben bereits diskutiert, warum die von Ihnen geposteten Leistungsvergleiche von einer schlecht implementierten API ausgehen und keinen Sinn ergeben.

Der Fehlervergleich ist ebenfalls ungültig. Da momentjs eine Verkettungs-API unterstützt, könnte man erwarten, dass sie unveränderlich ist.

var newM = m.year(2005) // wrong, these are both the same!

Sowohl unveränderlich als auch veränderlich haben im Moment also das gleiche Problem. Sie könnten es mit der aktuellen veränderlichen Version vermeiden, wenn Sie die Verkettungs-API loswerden.

Daher ist die unveränderliche API der veränderlichen vorzuziehen, da Sie sicher einen Moment zwischen den Funktionen verbringen können. Bei den aktuellen veränderlichen Momenten habe ich 2 Optionen, wenn ich einen Moment zwischen den Funktionen verpasse

1) Der wahnsinnig fehlerhafte Weg (der wahrscheinlich am häufigsten vorkommt): Untersuchen Sie den gesamten Quellcode, um sicherzustellen, dass es keine unerwünschten Mutationen gibt. Schreiben Sie Unit-Tests, um sicherzustellen, dass sich keine unerwünschten Mutationen einschleichen.
2) Der vernünftige Weg (nehmen wir stattdessen an, dass jeder dies tut), defensive Programmierung: Denken Sie daran, die clone()-Funktion aufzurufen, bevor Sie in meiner Funktion mutieren.

Mit der unveränderlichen API müssen wir nicht jedes Mal daran denken, clone() aufzurufen. Stattdessen müssen wir daran denken, die API-Funktion aufzurufen, mit der wir das Klonen vermeiden können, aber dies ist nur eine Leistungsoptimierung, kein Problem der Korrektheit.

Es ist ziemlich klar, dass Sie sich nicht die Zeit genommen haben, den unveränderlichen Anwendungsfall zu verstehen

Das ist eine unfaire Aussage. Mein Argument ist, dass ich die Vorteile sehe, aber nicht glaube, dass sie die Kosten überwiegen.

Sie können sicher einen Moment zwischen den Funktionen verbringen

Wir müssen nicht daran denken, Klon anzurufen

Ist dies nicht der Anwendungsfall für Unveränderlichkeit? Wenn es noch mehr gibt, das ich nicht verstanden habe, lassen Sie es mich bitte wissen, aber dies scheint das einzige Argument in den letzten Jahren zu sein.

@timrwood ja, das ist der ganze Fall.

Aber ich sehe kein Zeichen von Ihnen, das anerkennt, dass Ihr Fall _gegen_ Unveränderlichkeit (schreckliche Leistung, fördert eine andere Art von Fehler, die in der veränderlichen API nicht vorhanden ist) nicht gültig ist.

Ich denke, wir sollten bei der Sichtweise von ecmascript 5 bleiben und vielleicht eine Funktion hinzufügen, die das aktuelle Objekt einfriert, oder ein globales Flag, das automatisch eingefrorene Objekte erstellt

http://blogorama.nerdworks.in/preventextensionssealandfreeze/

vielleicht ein zusätzlicher Parameter im Konstruktor, um ein Freeze-Objekt zu erstellen, da ein Freeze-Objekt nicht auftauen kann

@lfnavess Ich dachte über freeze bevor ich die Kopie beim Schreiben erwähnte. Das Problem ist, dass ... niemand es verwendet / davon weiß, noch hilft es, wenn es keine Ausnahme auslöst (im nicht-strengen Modus) -- es erzeugt tatsächlich verrückte Fehler, die Sie verfolgen können.

@timrwood Ich glaube nicht, dass ich mein Beispiel klar gemacht habe. In der Zeile m.year(2014) // clone here meinte ich, dass Moment intern tatsächlich einen Klon erstellen würde (mehr Speicher zuweisen) und m automatisch auf diesen neuen Speicher zeigen würde. Nun, das bedeutet im Grunde, dass clone() auch ein bisschen Shell-Speicher zuweisen sollte (etwas, das auf die interne Datumsdarstellung hinweist), ich bin mir nur nicht sicher, wie viel dadurch gewonnen würde.

Erstellen einer halben Version von clone , die nur die Schnittstelle klont, und die Möglichkeit, die zugrunde liegenden Daten zu ändern (von gemeinsam genutztem Speicher zu instanzspezifisch) - es hängt wirklich davon ab, wie teuer Date-Objekte sind. Der Nachteil ist, dass jede Funktion this._storage._d anstelle von this._d , und ich bin mir nicht sicher, ob dies den Vorteil überwinden würde.

Ich habe keine Kommentare zum Umgang mit der Migration der vorhandenen Bibliotheken/Benutzer erhalten. Ich mag keine der oben aufgeführten Optionen wirklich.

Die Rückwärtskompatibilität ist IMO das stärkste Argument dagegen. Wenn wir dies tun, müssen wir einfach akzeptieren, dass es eine große bahnbrechende Veränderung ist. Wenn wir das nicht akzeptieren wollen, sollten wir es nicht tun.

Es ist erwähnenswert, dass re:perf auch einige große Vorteile aus der Unveränderlichkeit ziehen kann; es ist kein monotoner Perf-Hit. Sie können beispielsweise Dinge auf Objektebene zwischenspeichern, da sie sich nie ändern. Ich denke auch, dass wir in der Lage sein sollten, den lebenden Mist aus clone() zu optimieren; AFAIK beinhaltet das Klonen eines Datums und das Kopieren von fünf Werten; Ich denke, wir sollten sie einfach hartcodieren wie newThing._offset = oldThing._offset .

Edit, arg, no - Plugins fügen auch Felder hinzu (zB hier ).

Angesichts des starken Wunsches nach Abwärtskompatibilität und dennoch geringem Gewicht, denke ich, dass die beste Lösung darin besteht, die Javascript-Quellen zu forken (entweder in den Quellen dieses Projekts oder ein völlig neues Projekt zu starten). Es gibt Platz für mehr als 1 Mal Bibliothek für das Internet.

Auch: Re: @ichernevs Idee zur strukturellen gemeinsamen Nutzung, eine Möglichkeit besteht darin, die Prototypvererbung zu verwenden, anstatt ein gemeinsames Zustandsobjekt zu umhüllen.

Wir von WhoopInc lauern schon seit einiger Zeit in dieser Diskussion. Da sich die Diskussion hier im Kreis zu drehen scheint, habe ich mir dieses Wochenende etwas Zeit genommen, um zu erkunden, wie eine unveränderliche Version von Moment mit einer Builder-API aussehen könnte. (Ich habe nicht die Absicht, eine PR gegen den Moment einzureichen, es sei denn, ich werde dazu aufgefordert, da ich absichtlich schärfere API-Änderungen vornehme, als ich jemals im Moment selbst erwarten würde.) Hier ist das Ergebnis: https://github. com/WhoopInc/frozen-moment

Ich bin nur ein paar Stunden drin, also ist alles wirklich rau an den Rändern, aber basierend auf den Testergebnissen denke ich, dass die meisten der Kernmomentfunktionen funktionieren. Ich werde diese Konversation weiterhin verfolgen und würde mich über Feedback zu unserem Fork in unseren Repos-Problemen freuen.

Ich werde heute Abend versuchen, einige aktualisierte Dokumente zu diesem Repo zu veröffentlichen, aber im Grunde habe ich einfach alle Setter- und Mutationsmethoden in ein separates Builder-Objekt aufgeteilt. Die Verwendung der API könnte also wie folgt aussehen: frozenMoment("2014-07-21").thaw().subtract(1, "day").startOf("day").freeze().format("YYYY-MM-DD") . (Obwohl es in diesem speziellen Beispiel effizienter wäre, die Kette einfach mit einem Builder zu starten, anstatt einen Builder von einem frozenMoment mit frozenMoment.build("2014-07-21").subtract... initialisieren)

FWIW, als ich anfing, Moment zu verwenden, war ich davon ausgegangen, dass es den FP-Prinzipien folgt und jedes Mal, wenn ich eine Funktion aufrufe, denselben Wert zurückgeben würde:

var now = moment();
var yesterday = now.subtract(1, 'days');
var dayBeforeYesterday = now.subtract(2, 'days');

Natürlich habe ich nicht die Ergebnisse erhalten, die ich erwartet hatte. Das hat mich als neuen Benutzer überrascht.

Betrachten Sie diesen Pseudocode, der zeigt, wie ich das Verhalten des Codes erwartet hätte:

var now = now;
var yesterday = now - 1day;
var dayBeforeYesterday = now - 2days;

Aber stattdessen hat es so funktioniert, was sich für mich seltsam anfühlt:

var now = now;
var yesterday = now = now - 1day;
var dayBeforeYesterday = now = now - 2days;

Im Moment, auch wenn es ziemlich mühsam ist, habe ich nur vorsichtig .clone() überall.

var now = moment();
var yesterday = now.clone().subtract(1, 'days');
var dayBeforeYesterday = now.clone().subtract(2, 'days');

IMO, Javascript ist anfällig für subtile Fehler und ich glaube, dass FP-Prinzipien dazu beitragen, diese Fehler zu minimieren.

Ich habe Verständnis dafür, dass dies eine schwere Entscheidung ist. Ich schätze Ihre Arbeit. Moment.js ist unglaublich.

+1 für 100 % Unveränderlichkeit.

Es ist ehrlich gesagt frustrierend, dass es nicht unveränderlich ist.

+1 für 100 % Unveränderlichkeit in Version 3

Es sollte auf jeden Fall eine unveränderliche API geben. Als Benutzer anderer Datumsbibliotheken (insbesondere .NET DateTime und Joda Time / Noda Time) erwarte ich intuitiv, dass die Methode add das Datumsobjekt nicht mutiert.

+1 für Unveränderlichkeit

+1 für 100 % Unveränderlichkeit

Wenn die Entscheidung für Unveränderlichkeit getroffen wird, wäre ich bereit, meine Zeit zu investieren, um dies zu erreichen. Vielleicht Pairing über einen Videoanruf. Ich würde gerne mehr zu Open Source beitragen, muss aber die Grundlagen erlernen.

Für mich ist Unveränderlichkeit vorzuziehen, aber es hätte von Anfang an getan werden sollen. Dies ist eine drastische Veränderung. Ein Fork dieses Projekts, das sich auf Unveränderlichkeit konzentriert, wäre eine bessere Idee.

@dsherret Dafür ist

Mit einigem Aufwand könnte es jedoch als Konfigurationsoption eingeführt werden: "Wollen Sie alles unveränderlich? Richtig oder falsch". Standard wäre false.

Nicht unterstütztes inoffizielles ymmv-Immutable-Moment-Plugin hier: https://gist.github.com/timrwood/fcd0925bb779f4374a7c

Haha! Ich war überrascht, so viel später hierher zu kommen und zu entdecken, dass ich einer der ersten Befürworter einer unveränderlicheren API war. :) :)

Und ja, ich bin +1 für Unveränderlichkeit für die nächste Hauptversion.

Noch ein +1 für unveränderlichen Moment von mir.
Und hier ist mein 'imoment'-Gebräu: https://gist.github.com/idrm/a91dc7a4cfb381dca24e (Benutzung auf eigene Gefahr!). Ersetzen Sie einfach Ihre moment()-Aufrufe durch imoment() und das sollte ausreichen. Alle statischen Funktionsaufrufe moment.xyz() (zB moment.min(), moment.max(), etc.) sollten unverändert bleiben.

+1 Million Dollar

+1 für Unveränderlichkeit

Darf ich auch ein +1 zu einem früheren Vorschlag aus diesem Diskussionsthread hinzufügen, um einige der Funktionen umzubenennen, damit sie leichter zu lesen sind ("startOf" zu "toStartOf", "add" zu "plus", "month" in "withMonth" ", etc.)? Das heißt, vorausgesetzt, Sie nehmen die standardmäßig unveränderliche Route. Ich benutze Joda Time viel, und es ist ein Kinderspiel, herauszufinden, was zum Beispiel "date.withDayOfMonth(1).withDayOfWeek(DateTimeConstants.MONDAY)" bedeutet.
Diese müssen sich auch nicht in der Hauptdistribution JS befinden; ein Add-On, das diese auf das Vanilla-JS legt, würde genauso gut funktionieren (verdammt, ich erwäge stark, selbst ein solches Add-On zu schreiben, das auf Joda Time ausgerichtet ist, um es mit meinem "imoment" -Mod zu kombinieren).

@ichernev , @icambron , hast du dich dazu entschieden? Werden Momente in 3.0 unveränderlich sein? Wenn ja: Wann wird 3.0 voraussichtlich erscheinen? Ich frage, weil ich überlege, Frozen-Moment zu verwenden oder selbst ein kleines Wrapper zu schreiben – und frage mich, ob ich warten soll.

Zu Ihrer Information, Frozen-Moment befand sich in letzter Zeit hauptsächlich in einer Warteschleife – ich habe eine Reihe von PRs von Upstream-Moment portiert, aber nicht wirklich an anderen Refactorings gearbeitet, die idealerweise in diesem Fork stattfinden sollten.

Das heißt, Frozen-Moment sollte gut funktionieren, wenn Sie nur das englische Standardgebietsschema benötigen. (Alles funktioniert für meine Anwendungsfälle, und ich habe die hohe Unit-Test-Abdeckung von Moment beibehalten.) Nicht-englische Gebietsschemas sind defekt, weil ich sie nach der Portierung der kürzlich überarbeiteten Gebietsschema-APIs von Moment nicht aktualisiert habe.

Sobald wir eine Entscheidung für Moment 3.0 getroffen haben, plane ich, etwas ernsthafter an der Unveränderlichkeitsarbeit in Moment oder an der Frozen-Moment-Gabel, je nach Bedarf, zu arbeiten. Mein ursprüngliches Ziel wäre es, die Unterstützung für das Gebietsschema zu beheben und die Funktionsparität mit der API von Moment 3.0 aufrechtzuerhalten.

+1 für Unveränderlichkeit

+1 für Unveränderlichkeit. Was ist mit der Methode format , die auch das Objekt mutiert?

+1 für einen unveränderlichen Moment.js
Oder vielleicht ein Fork von moment.js? unveränderlicher-moment.js? Denn dies wird definitiv ein Breaking Change sein.

:100:
mach die imootables!

+1 Unveränderlichkeit ist heutzutage etwas, was ich von jeder guten JS-API erwarte

:+1: Ja bitte, das würden wir sehr gerne. Derzeit streuen wir .clone() überall hin.

+1 das wäre eine sehr schöne verbesserung

:+1: unveränderlich all die Dinge

+1 für unveränderlich

Machen Sie alles unveränderlich. Ich habe es satt, jede Moment(jetzt)-Variable zu klonen, bevor ich die Jetzt-Variable operiere und dann die Jetzt-Variable wieder geändert wird.

+1 für Unveränderlichkeit

Ich hätte nicht erwartet, dass startOf('day') mutiert (obwohl ich zugeben muss, dass es gut dokumentiert ist, wenn ich genauer gelesen hätte). Das verursachte einen lustigen Fehler in meiner Anwendung.

Ich stimme definitiv zu, dass die meisten moment.js-Operatoren in ihrer Veränderlichkeit umständlich sind. mmnt.startOf('day') ist super kontra intuitiv, indem es mmnt mutiert.

Ich verwende moment.js für Anwendungsfälle vom Typ Kalender mit vielen Schleifen und Datumsvergleichen. Ich habe die Leistungsprobleme mit clone() und sie sind grauenhaft. Eine gewisse Kontrolle darüber zu haben, was Klone und was mutiert, ist für mich und wahrscheinlich auch für andere von entscheidender Bedeutung.
Auch wenn clone() überall auf den ersten Blick unangenehm erscheint, ist das, was es tut, kristallklar und machte das Refactoring für die Leistung für mich super einfach.

Wenn jede Methode blindlings mit clone() beginnt, um eine schönere API zu haben, haben wir den Punkt meiner Meinung nach verfehlt.

meine 2¢ :-)

@jdurand Ich würde eher explizit mutieren als explizit klonen.

@dsherret Mir macht nichts explizit etwas aus. Mein Hauptanliegen ist, nicht implizit zu klonen, da dies eine sehr kostspielige Operation ist.
Jemand erwähnte, dass Setter eine geklonte Kopie zurückgeben müssten, und das machte mir Angst; Es wäre sehr ineffizient.

@jdurand es könnte ineffizienter sein, aber ich denke, ein impliziter Klon würde den meisten Anwendungen zugute kommen, bei denen der Unterschied zwischen geklonten und mutierten Objekten keinen merklichen Unterschied für die Erfahrung des Endbenutzers machen würde. Ich denke, dass die Einfachheit der Entwickler und der Versuch, Entwicklerfehler zu vermeiden, Vorrang vor ein paar eingesparten Millisekunden haben sollten, da die Mehrheit der Entwickler nicht Tausende von Datumsoperationen gleichzeitig durchführt. Für diejenigen, die es sind, könnten sie vielleicht explizit sagen, dass sie mutieren möchten, anstatt zu klonen.

Randbemerkung: Mit dieser Änderung könnten meiner Meinung nach jedoch einige Leistungsverbesserungen vorgenommen werden ... zum Beispiel könnte das Klonen beseitigt werden, indem stattdessen auf das vergangene unveränderliche Objekt verwiesen und dann die für dieses Objekt auszuführende Operation gespeichert wird (z. B. add(1, 'days') ). Das Ergebnis würde dann nur durch Ausführen der Operationen berechnet, wenn etwas wie .toString() , .format() , .toDate() , .day() usw. aufgerufen wird. Das wäre eine dramatische Änderung und es könnte am Ende nicht schneller gehen ... einige Unit-Tests müssten durchgeführt werden, um die Leistung zu vergleichen (zusätzlich könnte es andere Probleme geben, die ich nicht berücksichtigt habe, da ich mir noch nie einen Code angesehen habe in moment.js anders als beim Klonen).

@dsherret Ich mag den _builder_/_lazy_-Ansatz; im nachhinein sollte es wohl von anfang an so gebaut worden sein.
Wie Sie sagten, denke ich, dass ein unveränderlicher Fork mit API-Kompatibilität das Beste wäre.

2 Cent mehr:

  1. Sollten wir uns wirklich Sorgen um die Leistung machen, wenn der Moment eindeutig auf Komfort und nicht auf Leistung ausgelegt ist? Ich würde denken, dass das Parsen von 'Jahr' in m.add('year',1) viel langsamer ist als das Klonen.
  2. Es sei denn, es gibt einen vollständigen Fork (anderer Name, anderes Dokument), wird es eine Qual sein, 2 Versionen zu pflegen. Ich denke, jemand, der clever ist, sollte eine Idee haben, moment.immutable.min.js und moment.min.js aus derselben Codebasis zu generieren ...

Seit wann haben wir solche Angst vor Veränderungen? Die aktuelle Version ist stabil und kann weiterhin verwendet werden, ohne ihre Codebasis umzugestalten.

Die Pflege von zwei Codebasen ist mühsam, verlangsamt Sie und ist es nicht wirklich wert, nur eine veränderliche/unveränderliche Version zu haben.

Also lass uns einfach mit einem völlig unveränderlichen Moment gehen, die Hauptversion stoßen und fertig :dancers:

Ich habe diesen Thread gefunden, als ich gerade angefangen habe, diese Bibliothek zu verwenden, aber ich habe mir die Haare ausgerissen, um Code zu debuggen und mich mit unvorhersehbaren Nebenwirkungen der Veränderlichkeit zu befassen. Würde gerne eine vollständig unveränderliche Version der Bibliothek sehen!

Schamloser Stecker: Ich habe es satt, hier auf eine feste Entscheidung zu warten. In den letzten Tagen habe ich Frozen Moment wiederbelebt und neu geschrieben, um als Plugin für Moment selbst zu fungieren. Hut-Tipp an @wyantb, der mir geholfen hat, die erste Vorschauversion über das Wochenende zu

Frozen Moment bietet einen unveränderlichen Typ, der genau wie Moment funktioniert. Grundsätzlich umschließt die unveränderliche Version die Funktionalität von Moment und ruft .clone() Bedarf

Für diejenigen, die Builder-APIs mögen, möchte ich Sie auffordern, Moment selbst als eine sehr schöne Implementierung eines Builder-Objekts zu betrachten! Frozen Moment fügt den unveränderlichen Kerntyp hinzu, den wir alle wollen, und einen Mechanismus zum Erstellen eines unveränderlichen Frozen Moment aus einem veränderlichen Moment.

Für diejenigen, die einfach nur mit einer praktischen unveränderlichen API arbeiten möchten – nun, ich beabsichtige auch, dies zu unterstützen. Ich habe noch keinen Konstruktor erstellt, der direkt eine Frozen-Instanz erstellt, aber das steht auf der TODO-Liste . Kurzfristig besteht die Problemumgehung darin, alles mit moment().freeze() oder moment.utc().freeze() zu erstellen.

Frozen Moment ist offensichtlich eine junge Codebasis, daher gibt es wahrscheinlich ein paar Ecken und Kanten – aber ich möchte jeden hier ermutigen, es auszuprobieren und Probleme für alles zu melden, was nicht so funktioniert, wie Sie es erwarten.

Oh, noch etwas: Ich mache noch keine Werbung dafür, aber Frozen Moment-Instanzen sollten mit den meisten Moment-Plugins "einfach funktionieren". Stellen Sie einfach sicher, dass sich alle Ihre anderen Moment-Plugins vor Frozen Moment registrieren. Wenn Sie ein Plugin finden, das mit unveränderlichen Frozen Moments nicht wie erwartet funktioniert, melden Sie einen Fehler und ich werde mich darum kümmern.

+1 auf Unveränderlichkeit

+1 für unveränderlich

Hat sich jemand die Implementierung von Moment auf Immutable JS angesehen ? Es ist eine optimierte Bibliothek für Unveränderlichkeit in JS, sie verwendet unveränderte Teile eines unveränderlichen Objekts wieder und reduziert so Speicherprobleme.

+1
Aus diesem Grund habe ich gerade einen 3 Jahre alten Fehler behoben: https://github.com/Saleslogix/argos-saleslogix/commit/87b35b22c1a42670da369701b15e2bdb3786cabc

Die Benutzer verlangen also Unveränderlichkeit, aber das Kernteam findet Ausreden, dies nicht zu tun? :P
Kommt schon Leute, diese Änderung ist viel wichtiger, als den Code in ES6 neu zu schreiben ^^ In ihrer aktuellen Form ist die API einfach schlecht, ein bisschen wie die des JS-Arrays, bei der einige Methoden unveränderlich sind (Filter, Concat usw.), aber einige andere sind es nicht (umgekehrt, sortieren), außer dass ihre Einschränkung für die Abwärtskompatibilität unendlich höher ist als bei einer Bibliothek.

+1

eine kleine Falle, die mich immer erwischt (und das ist IMHO ein guter Grund für Unveränderlichkeit):

var today = moment();
for (var i = 0; i < 7; i++) {
   week.push(today.subtract(i, 'days').format('dd').toUpperCase());
}

Dies erzeugt leider kein Array mit den Tagesnamen, sondern etwas Seltsames, da Sie das Datum tatsächlich so berechnen:

i = 0 = today -0;
i = 1 = today -0 -1;
i = 2 = today -0 -1 -2;
etc

Sie müssen es also umgestalten:

var today = moment();
for (var i = 0; i < 7; i++) {
            if (i == 0) {
                week.push(today.subtract(0, 'days').format('dd').toUpperCase());
            }
            else {
                week.push(today.subtract(1, 'days').format('dd').toUpperCase());
            }
        }

@faebser ausgezeichnetes Beispiel

+1 für Unveränderlichkeit

+1

@faebser ist mir heute morgen passiert. Die Zwei-Wege-Bindung + Veränderlichkeit von Angular macht es schwer, Klondaten beizubehalten, um die aktuellen nicht zu ändern.

+1 für Unveränderlichkeit, das hat mich nur ein paar Stunden gekostet.

:+1:

+1 für Unveränderlichkeit

Ich bin etwas hin- und hergerissen bei diesem Thema.

Der Purist in mir möchte schreien "+1 für Unveränderlichkeit! Moment-Objekte sind eindeutig vom Typ ValueObject ".

Wir können jedoch nicht ignorieren, dass moment.js das 13. beliebteste Javascript-Repository auf GitHub (und das 24. insgesamt) ist und dass die Suche nach "moment" auf bower.io 111 übereinstimmende Ergebnisse zurückgibt. Selbst wenn wir Anwendungsentwicklern eine schrittweise Möglichkeit bieten können, eine unveränderliche Version von Moment zu implementieren, wird dies ein großes Durcheinander zwischen den Abhängigkeiten verursachen.

@ichernev Vielleicht ein bescheidenerer Vorschlag: Wäre es möglich, einen kleinen Teil der Dokumentationsseite von Moment dem Gespräch über Veränderlichkeit vs. Unveränderlichkeit zu widmen? Sie könnten kurz Ihre offizielle Haltung zu dem Thema darlegen und vielleicht eine kurze Zusammenfassung der Argumente hinzufügen, einen Link zu diesem Thread platzieren oder wenn Sie einen spezifischen Diskussionsbeitrag wünschen, könnte es wie ein CTA funktionieren.

Im Moment wird auf der Dokumentationsseite der Begriff "unveränderlich" nicht erwähnt. Wenn Sie "moment unveränderlich" googeln, gelangen Sie auf diese Seite, aber ich habe zwei Stunden zum Lesen gebraucht und bin mir immer noch nicht sicher, wie Ihre aktuelle Haltung zu diesem Thema ist. Es wäre toll, wenn Googles Top-Hit für "Moment Immutable" eine schnelle Antwort auf die Zukunft der Unveränderlichkeit im Moment geben würde :)

Um @jehoshua02 zu zitieren:
"Ich habe Verständnis dafür, dass dies eine schwere Entscheidung ist. Ich schätze Ihre Arbeit. Moment.js ist unglaublich."

Hier ist mein Vorschlag. Anstatt das Basismoment unveränderlich zu machen, fügen Sie eine moment.immutable Factory hinzu. Es wäre eine Eigenschaft der Funktion moment und würde dieselbe API-Signatur wie moment umschließen, aber unveränderlich.

Es könnte sogar nur eine prototypische Erweiterung der veränderlichen moment Factory sein, die die Funktionen dieses Prototyps verwendet, aber stattdessen klont.

EDIT: Es scheint, dass WhoopInc / Frozen-Moment genau das ist, wonach ich suche.

@thomasvanlankveld Breaking Changes sind die Hauptversionsnummern. Jeder, der Bower und npm verwendet, hat die Möglichkeit, bei der aktuellen Hauptversionsnummer zu bleiben; wir sollten uns hier keine Sorgen um die Abwärtskompatibilität machen - außer vielleicht den Leuten, die dies nur von CDN aus bereitstellen. Aber wenn sie momentjs von CDN verwenden, sind sie wahrscheinlich sowieso nicht sonderlich daran interessiert, die Bibliothek von Zeit zu Zeit zu aktualisieren.

Ich würde argumentieren, dass die Unveränderlichkeit in der nächsten Hauptversion - oder der Hauptversion danach - auf der Roadmap stehen sollte.

Scheint also auch gerade auf dieses Problem gestoßen zu sein.

http://stackoverflow.com/questions/33002430/moment-js-formatting-incorrect-date

Ich bin also auf ganzer Linie für Unveränderlichkeit.

+1 Für Unveränderlichkeit

Habe gerade einen Abend durch dieses überraschende und unerwartete Verhalten verloren.
Ein weiteres +1 für Unveränderlichkeit mit einer entsprechenden größeren Versionsänderung, um es deutlich zu machen.

+1 Für Unveränderlichkeit

+1 für volle Unveränderlichkeit.
Die Gesamtzahl der verlorenen Stunden durch "manchmal veränderlich, manchmal unveränderlich" muss ziemlich groß sein.

Ja ich meine ernst. Wen interessiert die Leistung in einer Datetime-Bibliothek? Wie wirklich? Ich schätze, 99,9 % der Benutzer tun nichts, was auch nur aus der Ferne eine gute Leistung erfordert. Typischerweise bearbeiten Sie ein paar Daten oder im schlimmsten Fall ein paar Hundert. Die wenigen Benutzer, die Millionen von Daten pro Sekunde verarbeiten, können optimierte veränderbare API-Punkte verwenden.

Unveränderlichkeit ist die einzige vernünftige Designwahl. Es gibt mehrere Studien, die zeigen, dass die Programmierung mit unveränderlichen Typen viel weniger fehleranfällig ist als mit veränderlichen Typen.

+1 für Unveränderlichkeit. Das hat mich ein paar Stunden gekostet.

Ein Teil des Problems ist, dass Methodennamen wie .startOf() keine Mutation des zugrunde liegenden Objekts implizieren.

Ich bin mit Moment auf Leistungsengpässe gestoßen, daher kann ich Ihnen versichern, dass dies manchmal passieren kann.

Ich bin jedoch nicht davon überzeugt, dass unveränderliche Momente von Natur aus weniger effizient wären, und kann mir einige Fälle vorstellen, in denen sie effizienter wären.

Diese Debatte wurde in der Java-Welt vor langer Zeit beigelegt. Unveränderliche Daten gewannen und die beliebteste Implementierung (JodaTime) wurde schließlich Teil der Standardbibliothek in Java 8.

Die Arbeit mit LocalTime Java 8 war eines dieser 'Warum haben wir das nicht _immer_ gemacht''. Momente. Ich evangelisiere selten Technologien, aber ich kann ehrlich gesagt keine Vorteile bei veränderlichen Datumsobjekten sehen.

Also, ja .... Ich hasse es, dass diese Threads mit +1 überflutet werden, aber die Wahrheit ist, dass jemand anderes eine unveränderliche JS-Datumsbibliothek erstellen wird, wenn Moment dies nicht tut.

Ich bin kürzlich über ein neues npm-Modul gestolpert, das vorgibt, einen Großteil der JodaTime-API (dh Java 8-Daten) auf JS zu portieren.

Dies würde Dinge wie Unveränderlichkeit, LocalDate und LocalTime zum Knoten und zum Browser bringen.

Nachdem ich mit diesen Konzepten in Java gearbeitet habe, fühlt sich alles andere ungeschickt und fehleranfällig an.

Verknüpfung?

Am Freitag, 11. Dezember 2015, 16:30 Uhr Andrew Schmadel [email protected]
schrieb:

Ich bin vor kurzem über ein neues npm-Modul gestolpert, das vorgibt, viel zu portieren
die JodaTime-API (dh Java 8-Daten) zu JS.

Dies würde Dinge wie Unveränderlichkeit, LocalDate und LocalTime ins Spiel bringen
Knoten und den Browser.

Nachdem ich mit diesen Konzepten in Java gearbeitet habe, fühlt sich alles andere klumpig an
und fehleranfällig.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/moment/moment/issues/1754#issuecomment -163964349.

Wout.
(auf dem Handy getippt, Entschuldigung der Knappheit)

Da ich mich noch nicht eingemischt habe, sage ich nur, dass ich im Moment 3.0 für Unveränderlichkeit bin. In erster Linie, weil ich von der DDD-Denkschule komme, wo Objekte wie moment als _Wertobjekte_ betrachtet würden und daher am besten als unveränderlich implementiert werden.

Selbst wenn es einen erheblichen Leistungseinbruch gibt, ist es immer noch das Richtige. Moment sollte sich natürlich in die Designs anderer einfügen. Intuitive API übertrumpft Perf, und Mutation ist bei Wertobjekten (IMHO) nicht intuitiv.

Ich denke auch, dass Moment 3.0 seine Abhängigkeit vom Date Objekt entfernen sollte, aber das ist eine Diskussion für einen anderen Thread.

Ich stimme @mj1856 hier

Ich habe Object.freeze für Momentinstanzen verwendet und dies hat im Allgemeinen das erreicht, was ich brauchte; außer ich habe gerade festgestellt, dass Folgendes fehlschlägt:

let now = Object.freeze(moment());
if (now.isSameOrBefore(anotherTime)) { // throws exception
}

Die Ausnahme:

TypeError: Can't add property _isValid, object is not extensible
 at valid__isValid (C:\git\quick-test\node_modules\moment\moment.js:93:24)
 at Moment.moment_valid__isValid [as isValid] (C:\git\quick-test\node_modules\moment\moment.js:2195:16)
 at Moment.isSame (C:\git\quick-test\node_modules\moment\moment.js:1945:44)
 at Moment.isSameOrBefore (C:\git\quick-test\node_modules\moment\moment.js:1962:21)

Kann dies behoben werden, sodass Object.freeze auf Wunsch verwendet werden kann?

@wmertens Ich nehme an, das ist es: https://github.com/pithu/js-joda

@ichernev , @mj1856 , da ich seit einiger Zeit nicht mehr an der Entwicklung des großes Interesse hat , ziehe ich meine vorherige Haltung zurück.

Ich bin mir nicht sicher, ob ich der einzige Blockierer war, aber ich fühle mich wohl, mit der Unveränderlichkeit in 3.0 voranzukommen.

@gabrielmaldi @wmertens Ja . Das war es. Entschuldigung für meinen grenzwertig inkohärenten Kommentar – ich habe in einem halbwegs geschriebenen Beitrag eindeutig auf die Schaltfläche „Senden“ geklickt.

Um einige meiner zusammenhanglosen Gedanken zusammenzufassen:

  • Es besteht eindeutig ein gewisses Interesse an unveränderlichen Datumsobjekten für JS. Es gibt ausgereifte unveränderliche Datumsbibliotheken in mehreren anderen Sprachen, und es gibt eine große allgemeine Dynamik in Richtung unveränderlicher Objekte in JS ( immutable.js hat 10.500 Sterne, wenn das ein Hinweis ist). Zumindest denke ich, dass dies einen Proof-of-Concept verdient.
  • Trotz dieses Interesses scheint nur sehr wenig Code geschrieben worden zu sein. js-joda scheint der erste ernsthafte Versuch zu sein, eine unveränderliche
  • Unveränderliche Momente wären ein großer Durchbruch, der einige philosophische Fragen aufwirft. Obwohl ich es hassen würde, die Unterstützung der sehr großen MomentJS-Community zu verlieren, wäre es nicht unbedingt eine schreckliche Sache für diejenigen von uns, die an unveränderlichen JS-Daten interessiert sind, einen sauberen Bruch zu machen und zu js-joda beizutragen, anstatt es zu versuchen eine ziemlich radikale Änderung bei Moment (einer ausgereiften Bibliothek mit einer großen und etablierten Benutzerbasis) voranzutreiben.
  • Übrigens: js-joda ist noch sehr jung, und es ist unklar, welche Ziele und Absichten der Autor für die Bibliothek hat. Insbesondere muss er eine Lizenz auswählen, und wir sollten überlegen, ob die Anforderungen eines typischen JS-Entwicklers durch eine originalgetreue Neuimplementierung von Joda Time oder JSR-310 erfüllt würden.

+1 für eine Unveränderlichkeit und den daraus resultierenden vernünftigeren Code.

Es wird eine große Anstrengung sein, daher ein aufrichtiges Dankeschön an diejenigen, die es möglich machen (und getan haben).

Moment ist weit verbreitet genug, dass ich denke, es wäre umsetzbar, mit etwas in der Nähe des Folgenden zu gehen, vorausgesetzt, das wird ähnlich wie https://github.com/WhoopInc/frozen-moment von @butterflyhug implementiert

3.x: als Option unveränderlich, standardmäßig auf "false" gesetzt und ein Flag für den globalen Momentexport gesetzt, das auf "true" gesetzt würde; console.warn beim Laden der Bibliothek (im Entwicklungsmodus)
4.x: als Option unveränderlich, standardmäßig auf "true" gesetzt, Flag noch verfügbar, um auf "false" gesetzt zu werden; console.warn über Zeitplan für 5.x (im Entwicklungsmodus)
5.x: als einzige Möglichkeit unveränderlich

Haben Sie eine Seite im Vordergrund und in der Mitte, die die langfristige Vision der Unveränderlichkeit beschreibt - sagen wir, eine Hauptversion pro Jahr entlang der von mir erstellten 3.x/4.x/5.x-Gliederung - und ich denke, es wäre ein vernünftiger Betrag für alle Betroffenen, um ihren Code zu aktualisieren.

Ein paar Beobachtungen:

  1. Ich habe WhoopInc/frozen-moment in der Hoffnung entwickelt, dass ein paar Leute hier bereit sind, Dinge damit zu bauen, um Problempunkte im Moment-Ökosystem zu finden, an denen Unveränderlichkeit Plugins kaputt machen würde usw. Bisher haben das nur wenige Leute getan , was mich weniger daran interessiert hat, an Frozen-Moment- und/oder Community-Evangelisation zu arbeiten, um Plugin-Autoren dabei zu helfen, unveränderliche Momente zu unterstützen.

Trotzdem bin ich immer noch bereit, Fehler zu beheben, die Leute bei der Verwendung von Frozen-Moment finden - unabhängig davon, ob diese Fehler von mir stammen oder in einem anderen Moment-Plugin enthalten sind, das nie die Möglichkeit in Betracht gezogen hat, dass Momente unveränderlich werden. Melden Sie einfach Probleme im eingefrorenen Moment und ich schaue mir das an. Und ich denke immer noch, dass eine Community-Bemühung um so etwas wie Frozen-Moment uns helfen könnte, den Schmerz eines Übergangs zu unveränderlichen Momenten zu verstehen und zu lindern.

  1. Wenn moment Unveränderlichkeit in 3.0 implementiert, wäre es für jemanden ziemlich einfach, einen Wrapper zu schreiben und zu pflegen, um die veränderliche Moment 2.x-API auf der unveränderlichen 3.x-API zu implementieren. Konzeptionell würde dies tatsächlich wie eingefrorener Moment aussehen: Überall, wo eingefrorener Moment implizit clone() s ist, würde dieser Veränderlichkeits-Wrapper stattdessen implizit seine interne Referenz in einen neuen unveränderlichen Momentwert ändern. Dies könnte auch dazu beitragen, den Übergang für Leute zu erleichtern, die moment in großen Codebasen verwenden.
  2. Ich bin bereit, potenzielle Probleme zu durchdenken und Unveränderlichkeit in Moment 3 zu implementieren, falls gewünscht.
  3. js-joda wird JSR-310 unter Verwendung einer BSD-Lizenz direkt in JavaScript portieren.

@butterflyhug - Danke für den Bau von Frozen-Moment! Ich war aufgeregt, als ich das herausfand, machte mir aber Sorgen, eine Abhängigkeit von meinem Projekt zum Frozen-Moment einzuführen, da der Wechsel von einem unveränderlichen Moment zu einem veränderlichen Moment eine große Aufgabe in meinem Code wäre, wenn die Unterstützung weggefallen wäre. Wenn es Ihr Ziel war, Feedback zu bekommen und Sie es aktiv unterstützen, dann tue ich das lieber. :-)

Ich weiß nicht, wie viele andere Menschen die gleichen Gedankengänge hatten.

Ich bin gespannt, ob die Leute hier der Meinung sind, dass die Unveränderlichkeit in Verbindung mit dem Gedanken untersucht werden sollte, die Abhängigkeit vom Date Objekt aus Leistungsgründen zu durchbrechen (oder sogar eine Art träge Auswertung hinzuzufügen).

Ich würde vorschlagen, die Dinge Schritt für Schritt zu gehen, @schmod. Das ist schon eine (anscheinend) große Veränderung

@RobertMcCarter Ja , ich plane, auf absehbare Zeit Frozen-Moment zu unterstützen, es sei denn / bis eine Option für Unveränderlichkeit in der Kernbibliothek implementiert wird - zum großen Teil, weil ich sie persönlich für einige Dinge verwende, die ich erwarte eine Weile halten. Allerdings decken meine Anwendungsfälle nicht das gesamte Moment-Ökosystem ab, daher verlasse ich mich auf das Feedback und die Nutzung von anderen, um zu erkennen, was wichtig ist.

+1 für Unveränderlichkeit, nachdem ich eine halbe Stunde damit verbracht habe herauszufinden, was mit meiner App passiert ist, nachdem ich endOf() zum ersten Mal verwendet hatte. Zugegeben, ich habe die Dokumente nicht sorgfältig gelesen, ich habe nur angenommen, dass eine Methode mit diesem Namen zum Beispiel das Ende des Monats zurückgibt und die Momentinstanz unberührt lässt. Um ehrlich zu sein, ist es eine Überraschung und ich finde es lächerlich, dass das nicht so passiert oder vielleicht ist mein Kopf zu sehr an die – meiner Meinung nach – enormen Vorteile einer – größtenteils – unveränderlichen API gewöhnt

+1 für Unveränderlichkeit :)

Unveränderlichkeit ist mir egal, lass diese ausgezeichnete Bibliothek in Ruhe!

@es6Test Aus welchen Gründen stimmen Sie der Unveränderlichkeit nicht zu? Gibt es andere konkrete Gründe als Widerstand gegen Veränderungen?

+1
Ich denke, es wird die Verwendung der Bibliothek erleichtern, wenn sie unveränderlich wäre, mein Code ist voller .clone () -Methoden und manchmal provozieren Veränderlichkeit sehr schwer zu findende Fehler.

+1 Bitte mehr Unveränderlichkeit ^_^

@danpantry Nachdem ich einige weitere Apps erstellt habe, habe ich meine Meinung geändert. Ich würde Unveränderlichkeit bevorzugen.

Aber ich hätte gerne noch einige Variablen, die veränderbar sind, ich füge sehr oft Tage zu Momenten hinzu und ich möchte nicht mehr Vars erstellen müssen, um das Ergebnis zu halten.

@es6Test Verwenden let wenn Sie es _wirklich_ nicht mögen?

let date = moment()
// with immutability
date = date.add(5)

Ich bin auch für Unveränderlichkeit. Das ist die einzige Funktion von Pythons datetime Bibliothek, die sie wirklich zum Leuchten bringt. Sie können Objekte herumwerfen, ohne sich Sorgen machen zu müssen, dass etwas sie verändert, genau wie bei Zeichenfolgen.

In der Welt von React / Redux ist Unveränderlichkeit von größter Bedeutung. Ich bin bereits auf einige knorrige Probleme gestoßen, weil der Moment nicht an sich unveränderlich ist. Die Leistung ist hier irrelevant, da sie abgeschwächt werden kann. Die ImmutableJs-Bibliothek von Facebook beweist, dass unveränderlich gemacht werden kann, ohne die Leistung zu beeinträchtigen.

Ich werde auch +1 für die Unveränderlichkeit geben. Bis dahin haben Sie keinen Vorteil der Unveränderlichkeit, also macht es keinen Sinn, auf halbem Weg zu handeln.

Unveränderlichkeit und funktionale Programmierung werden heute mehr denn je verwendet (und ich liebe es). Ich werde meine Zeit zur Verfügung stellen, um zu dieser Initiative beizutragen. Mitwirkende kontaktieren mich bitte und lassen Sie mich wissen, wie ich Ihnen helfen kann.

Das Team wollte dazu ein Update geben, da wir so viel Interesse hatten.

Zu diesem Zeitpunkt möchten wir Sie wissen lassen, dass wir Ihre Bedenken gehört haben. Das gesamte Betreuerteam stimmt zu, dass wir, wenn wir die Bibliothek von Grund auf neu schreiben würden, sie unveränderlich machen würden. Allerdings ist das derzeit nicht so.

Derzeit haben wir 4 Millionen NPM-Downloads pro Monat, zusammen mit einer unzählbaren Anzahl von Benutzern, die sich darauf verlassen, dass sie über andere Kanäle einen Moment erhalten. Alle diese Benutzer haben Code, der davon ausgeht, dass der Moment so änderbar ist, wie er es heute ist. Darüber hinaus haben wir viele Plugins, die darauf angewiesen sind, dass Moment änderbar ist.

Der Code ist einfach zu schreiben, aber die Support-Anforderungen dieser Art von Änderung sind für ein kleines Team, das dies in unserer Freizeit tut, schwierig zu bewältigen. Das heißt, wir sind bereit, darüber nachzudenken. Wir fragen uns aber:

  • Warum erfüllt das Frozen-Moment-Plugin nicht Ihre Anforderungen?
  • Benötigen Sie nur eine unveränderliche API (eine API, die immer einen Klon zurückgibt), oder müssen wir die Objekte aus irgendeinem Grund intern wirklich nicht mutieren?
  • Würde das Hinzufügen einer zweiten, unveränderlichen API zum aktuellen Code Ihren Anforderungen entsprechen?

Das Problem mit dem Plugin für den eingefrorenen Moment besteht darin, dass es sich um ein Opt-in und nicht um ein Opt-out handelt. Jeden
moment() benötigt ein .freeze(), damit es unveränderlich ist.

Der springende Punkt der Unveränderlichkeit ist, dass ich, wenn ich Objekt X habe, das weiß
Wenn ich es nicht ausdrücklich veränderbar mache, muss es unveränderlich sein.
Jede öffentliche Funktion, mit der ich ein Objekt intern ändern kann, ohne
explizite Veränderlichkeit ist problematisch.

Ich denke, ein Workaround besteht darin, mehrere Dinge zu tun:

  1. Fügen Sie dem aktuellen Code eine zweite unveränderliche API hinzu
  2. Haben Sie eine globale moment()-Einstellung, bei der, wenn sie auf den unveränderlichen Modus eingestellt ist, alle
    Die erstellten moment()-Instanzen sind unveränderlich, wenn ein veränderlicher Aufruf versucht wird.
    wird nicht mutieren und stattdessen Fehler mit entsprechender Meldung zur Verwendung von unveränderlich
    API-Aufrufe.

Das wird meiner Meinung nach jeden zufriedenstellen. Was denken Sie?

Am Montag, 23. Mai 2016 um 12:11 Uhr, Maggie Pint [email protected]
schrieb:

Das Team wollte dazu ein Update geben, da wir so viel hatten
Interesse.

Zu diesem Zeitpunkt möchten wir Sie wissen lassen, dass wir Ihre Bedenken gehört haben. Die
Das gesamte Betreuerteam stimmt zu, dass wir die Bibliothek aus dem geschrieben haben
von Grund auf, würden wir uns dafür entscheiden, es unveränderlich zu machen. So ist es jedoch nicht
es ist jetzt.

Derzeit haben wir 4 Millionen NPM-Downloads pro Monat, zusammen mit einem
Unzählige Benutzer, die sich darauf verlassen, dass sie einen Moment durch andere bekommen
Kanäle. Alle diese Benutzer haben Code, der erwartet, dass der Moment änderbar ist, da
es ist heute. Darüber hinaus haben wir viele Plugins, die sich auf den Moment verlassen
veränderlich.

Der Code ist einfach zu schreiben, aber die Support-Anforderungen dieser Art von
Veränderungen sind schwer zu meistern als kleines Team, das dies in unserer Freizeit tut
Zeit. Das heißt, wir sind bereit, darüber nachzudenken. Wir fragen uns aber:

  • Warum erfüllt das Frozen-Moment-Plugin nicht Ihre Anforderungen?
  • Benötigen Sie nur eine unveränderliche API (eine API, die immer ein
    Klonen), oder müssen wir aus irgendeinem Grund intern wirklich nicht mutieren
    Gegenstände?
  • Würde das Hinzufügen einer zweiten, unveränderlichen API zum aktuellen Code Ihren Anforderungen entsprechen?
    braucht?


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/moment/moment/issues/1754#issuecomment -221062274

Eric Lau vom Google Mail-Konto.

Danke für die Antwort @maggiepint.

  1. Ein paar Probleme mit dem Plugin für eingefrorene Momente: Es ist nicht die Standardeinstellung, es erfordert zusätzliche Arbeit, es ist weniger wahrscheinlich, dass es aktiv gewartet wird als unveränderlich gebaut. Ich denke, das größte Problem ist, es zu vergessen, besonders bei größeren Projekten mit vielen Ingenieuren.
  2. Die API sollte frei von Nebenwirkungen sein. Es ist gut, einen Klon zurückzugeben, aber wenn Sie auch das Originalobjekt ändern, wäre dies ein Nebeneffekt. Der folgende Code sollte start nicht ändern, wenn end deklariert wird:
start = moment();
end = start.add(10, 'minutes');
  1. Meinst du, zusätzlich zu 'add' Funktionen wie 'immutableAdd' zu haben? Wenn ja, dann technisch gesehen, insbesondere wenn Sie einen Wrapper erstellen, um unveränderliche Funktionen mit denselben Namen zu verwenden:
import "moment/immutable";
start = moment();
end = start.add(10, 'minutes'); // immutable version of add

Meiner Meinung nach eignet sich dieser Ansatz zu einem eleganten Upgrade für diejenigen, die die unveränderliche API verwenden möchten – vorhandener Code funktioniert weiterhin, niemand wird dazu gezwungen und erfordert weniger Änderungen für diejenigen, die die unveränderliche API verwenden möchten.

Wir haben die Absicht, den Code-Nebeneffekt frei zu machen. Das grundlegende Muster wäre, sich in die aktuellen Funktionen einzuklinken, sie clone aufzurufen und dann mit diesem Klon zu arbeiten.

Technisch gesehen sollten die Objekte jedoch mit Werten konstruiert werden, die sich nicht ändern, wenn Sie wirklich unveränderlichen Code erstellen. Dies würde jedoch die Schwierigkeit bei der Durchführung dieser Änderung erhöhen. Es ist viel einfacher, Klon zu nennen und dann das zu tun, was wir vorher gemacht haben.

Ich unterstütze Drews Idee:

import "Moment/unveränderlich";
Start = Moment ();
end = start.add(10, 'Minuten'); // unveränderliche Version von add

Das wäre großartig, da es sich um ein unveränderliches Opt-out handelt und keine Änderungen an
Funktionsnamen.

Am Montag, 23. Mai 2016 um 12:53 Uhr, Maggie Pint [email protected]
schrieb:

Wir haben die Absicht, den Code-Nebeneffekt frei zu machen. Das Grundlegende
Muster wäre, sich in die aktuellen Funktionen einzuklinken, sie Clone aufrufen zu lassen,
und dann diesen Klon bearbeiten.

Technisch gesehen sind die Objekte jedoch, wenn Sie wirklich unveränderlichen Code erstellen,
sollte mit Werten konstruiert werden, die sich nicht ändern. Das würde
erhöhen jedoch die Schwierigkeit, diese Änderung vorzunehmen. Es ist viel einfacher zu
rufe Klon auf und mache dann das, was wir vorher gemacht haben.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/moment/moment/issues/1754#issuecomment -221076796

Eric Lau vom Google Mail-Konto.

@ericlau-solid

  1. Haben Sie eine globale moment()-Einstellung, bei der, wenn sie auf den unveränderlichen Modus eingestellt ist, alle
    Die erstellten moment()-Instanzen sind unveränderlich, wenn ein veränderlicher Aufruf versucht wird.
    wird nicht mutieren und stattdessen Fehler mit entsprechender Meldung zur Verwendung von unveränderlich
    API-Aufrufe.

Dies wird unterbrochen, wenn 2 Bibliotheken auf der Seite unterschiedliche Verhaltensweisen erwarten. Zum Beispiel verwenden Sie den Datepicker, der einen veränderlichen Moment erwartet, und Ihr eigener Code erwartet einen unveränderlichen - es wird nicht funktionieren.

Mit unveränderlicher API (ala Frozen-Moment)

Dies ist auch nicht perfekt, da keine Plugins damit funktionieren. Tatsächlich gibt es keine Möglichkeit, Unveränderlichkeit einzuführen UND alle vorhandenen Plugins funktionsfähig zu halten. Die Plugins funktionieren entweder überhaupt nicht oder funktionieren nicht mit unveränderlichen Momenten, bevor jemand die Zeit aufwendet, sie zum Laufen zu bringen.

import "Moment/unveränderlich";

Dies schlägt also im Grunde eine andere Bibliothek mit einer ähnlichen Schnittstelle vor. Sicher, es wird keinen Code beschädigen, aber es wird wahrscheinlich Verwirrung stiften und dazu führen, dass in einigen Projekten die 2 Versionen installiert sind (zum Beispiel nimmt der Datepicker die veränderliche Version und Ihr Code die unveränderliche).

Die beste Option besteht darin, eine API wie die aktuelle zu erstellen, jedoch mit unveränderlichen Objekten. Eine Gabel könnte in Ordnung sein. Das ist schließlich der Weg der freien Software.

Die Option "eine zweite API hinzufügen / ein Submodul veröffentlichen" wäre aus Gründen der Kompatibilität am besten, da Entwickler ihren Code inkrementell aktualisieren könnten. Die Bedeutung von moment() (über import moment; im Modul-Land oder das moment global im Browser-Build) sollte sich nach Möglichkeit nicht ändern, denn es gibt ein tonnenweise Legacy-Code da draußen.

IMO wäre eine Lösung ideal, die Folgendes ermöglicht:

import moment from 'moment';
import {immutable as immoment} from 'moment';

var a = moment(); // mutable moment
var b = moment().immutable(); // immutable moment
var c = immoment(); // also an immutable moment; shorthand

Keine andere Bibliothek, aber ja – haben zwei verschiedene und unterschiedliche Arten von Momenten. Unter der Annahme, dass die veränderlichen und unveränderlichen Momentobjekte eine beträchtliche Menge an Code "unter der Haube" gemeinsam haben, müsste die Bibliotheksgröße für Entwickler, die beide Syntaxen verwenden müssen, nicht viel erhöht werden. Wenn eine Anwendung nur eine Syntax verwendet, könnte Tree-Shaking verwendet werden, um einen optimierten Build zu erzeugen.

Das Verzweigen der Bibliothek würde möglicherweise die Größe des Codes verdoppeln, den die meisten Entwickler laden müssen, was für die meisten Webanwendungen unerwünscht wäre.


Ich glaube nicht, dass es eine gute Idee wäre, davon auszugehen, dass Plugins mit unveränderlichen Momenten "out of the box" funktionieren, und würde dies nicht als vernünftige Anforderung betrachten.

Ich denke auch nicht, dass es eine vernünftige Anforderung/Annahme ist, dass die veränderlichen und unveränderlichen APIs identisch sind. Wir sollten uns bemühen, den Upgrade-Pfad so reibungslos wie möglich zu gestalten, aber wir sollten uns nicht in irgendwelchen umständlichen Syntaxen festlegen.


Ich denke auch, dass es viel Raum für Debatten/Argumente darüber gibt, wie die "unveränderliche" API aussehen würde. Builder-Muster? Konstruktor-Instanziierung? Wertobjekt? Implementieren Sie die aktuelle API, aber geben "Setter"-Methoden einen Klon zurück?

Meine einzige Bitte ist, dass die neue API klar und eindeutig ist, mit welcher Art von Moment wir arbeiten. IMO, freeze diesen Test nicht und bietet wenig Schutz, außer jedes Mal clone() anzurufen, wenn ich einen Moment vergebe.

Dies schlägt also im Grunde eine andere Bibliothek mit einer ähnlichen Schnittstelle vor. Sicher, es wird keinen Code beschädigen, aber es wird wahrscheinlich Verwirrung stiften und dazu führen, dass in einigen Projekten die 2 Versionen installiert sind (zum Beispiel nimmt der Datepicker die veränderliche Version und Ihr Code die unveränderliche).

Keine separate Bibliothek, nur ein schlanker Wrapper um dieselbe Bibliothek. Es müsste nur eine Version von Moment installiert werden. Sie können 'moment/unmutable' importieren und datepicker kann 'moment' ohne Probleme in dasselbe Projekt importieren.

Es könnte ein Problem bei der Verbindung mit Plugins geben, die einen Moment aufnehmen oder zurückgeben, wenn sie nicht aktualisiert wurden, um unveränderliche Momente zu verarbeiten.

Angenommen, Sie geben einen unveränderlichen Moment an ein Plugin weiter, das es derzeit als veränderlich behandelt. Bis das Plugin aktualisiert ist, müsste es eine Möglichkeit geben, in veränderlich zu konvertieren, bevor dem Plugin ein Moment gegeben wird. Idealerweise würde es veraltet sein, nachdem Projektbetreuer etwas Zeit haben, um die Unveränderlichkeit zu unterstützen. Es müsste wahrscheinlich auch eine Möglichkeit geben, Unveränderlichkeit zu erkennen (für Plugin-Autoren).

Auf der anderen Seite kann eine Bibliothek, die aktualisiert wird, um die unveränderliche Schnittstelle zu verwenden, und den Benutzern einen unveränderlichen Moment zurückgibt, diejenigen verwirren, die keine unveränderliche Funktion verwenden und keinen unveränderlichen Moment erwarten. Ich glaube, dass dies auch durch eine veraltete Konvertierungsmethode gehandhabt werden kann. Plugins sollten einen Moment des gleichen Typs wie übergeben zurückgeben.

@maggiepint ja, ich verstehe Ihren Standpunkt, aber ich denke, das könnte ein zu großer Sprung sein. Persönlich wäre ich mit einem Ansatz einverstanden, der einfach clone hinter dem Vorhang steht. Vor allem während die Knicke bearbeitet werden.

@tacomanator das möchte ich auch machen. Es ist nicht sehr haltbar, das Ganze intern wirklich unveränderlich zu machen.
Ich wusste nur nicht, ob die Leute das aus irgendeinem Grund WOLLEN.

@schmod Könnten Sie kurz erläutern, warum freeze Ihrer Meinung nach keine klare und eindeutige API ist?

Wenn der Funktionsname zu süß ist, würde ich gerne ein Argument für die Umbenennung der Methoden von Frozen Moment als Problem in diesem Repository in Betracht ziehen. Auf der anderen Seite, wenn Sie der Meinung sind, dass es nicht möglich sein sollte, von veränderlich zu unveränderlich (und zurück) zu konvertieren, dann vermute ich, dass dies hier zu Diskussionen führen könnte – obwohl ich auch bereit wäre, Frozen Moment zu nehmen in diese Richtung, wenn wir einen groben Konsens erhalten, dass dies eine bessere API wäre.

@maggiepint Liege ich richtig, Kernbibliothek zu bündeln? Wenn es hilfreich wäre, würde ich gerne helfen, Frozen Moment oder einige seiner Ideen in die Moment-Organisation zu migrieren (entweder als offizielles Plugin oder als Teil der Kernbibliothek) und bei der Wartung in diesem neuen Kontext zu helfen.

@butterflyhug Du @ichernev gedacht hat. Er tendierte zum offiziellen Plugin, das mit der Bibliothek geliefert wurde. Vielleicht könnten wir das irgendwann in Gitter koordinieren? Ich muss geschäftlich drei Tage abwesend sein, daher habe ich nur begrenzte Verfügbarkeit. Der Rest der Jungs sollte in der Nähe sein.

@butterflyhug

Ich denke, dass freeze ein schöner Name ist, es ist einfach ätzend, daran denken zu müssen, ihn nach _jedem einzelnen_ Aufruf eines Augenblicks zu verwenden.

Ich denke auch, dass import 'moment/immutable' die gleichen Probleme hat, es ist leicht, es zu vergessen.

Ehrlich gesagt, Sie folgen Semver, ich denke, der richtige Ansatz besteht darin, alles _standardmäßig_ unveränderlich zu verwenden und diese Änderung als eigene Hauptversion zu veröffentlichen, mit dem Plan, ältere Versionen nach einem Zeitraum (12 Monate?) nicht mehr zu unterstützen. Neue Funktionen / Fixes könnten in beide Tracks, unveränderlich und veränderlich, mit einem Migrationsplan für Benutzer, die die veränderliche Version verwenden, zusammengeführt werden.

Nach den oben genannten 12 Monaten würden die alten Versionen _noch_ funktionieren, aber sie würden keine TLC erhalten.

Natürlich ist dies eine Menge Overhead, aber ich denke, es wäre besser, diese Änderung richtig vorzunehmen, als zu versuchen, sie im Interesse der Abwärtskompatibilität zu verfälschen. Es macht die Änderung auch viel komplizierter, was das Interesse des Kernentwicklungsteams abschrecken kann. Ich weiß nicht.

Ein weiterer potenzieller Nachteil dieses Ansatzes besteht darin, dass Benutzer dieses Skript von einem CDN aus verwenden und keine explizite Version angeben (aus welchen Gründen auch immer), was dazu führen kann, dass ihre Websites beschädigt werden, wenn eine abwärtskompatible API veröffentlicht wird. Alles, was ich dazu sagen kann, ist "Ich habe es Ihnen gesagt", aber ich verstehe, dass dies im Moment möglicherweise kein akzeptables Risiko ist.

Zwei Versionen derselben Bibliothek zu haben, wäre nur dann ein Problem, wenn Sie sich auf ein globales Objekt verlassen, und es gibt keinen wirklich guten Weg, dies zu umgehen, außer einfach weiterhin freeze() .


TLDR klingt so, als ob das Problem, das Sie lösen möchten, von semver gelöst wird, das Sie bereits verwenden. Warum nicht einfach so verwenden, wie es verwendet werden soll? Hauptversion für Breaking Changes. Der einzige Anlass, bei dem dies bricht, ist, wenn Sie sich auf eine globale moment Variable verlassen und ein CDN verwenden, aber jede Änderung, die wir hier vornehmen, wird dies sowieso brechen

Meine Stimme gilt auch für die Veröffentlichung von Semver und unveränderliche 3.0.

Ich habe keine Einwände gegen den Namen freeze , finde es jedoch von Natur aus problematisch, dass es schwierig ist, sichere Annahmen darüber zu treffen, ob ein Moment eingefroren ist oder nicht. ( Object.freeze() hat ein ähnliches Problem)

Ein unveränderlicher Moment sollte nicht auftaubar sein, und es sollte nie Zweifel geben, ob er eingefroren ist oder nicht. Dies könnte über eine strenge Variante des Builder-Patterns erreicht werden (dh das Objekt hat _nur_ Setter, bis .build() aufgerufen wird, danach hat es _nur_ Getter) oder einen Moment "eingefroren" zu lassen, sobald es wird instanziiert, wobei alle Setter einen Klon zurückgeben.

Zum Beispiel:

/* BUILDER PATTERN */
var bldr = moment.immutable()
  .hours(5)
  .minutes(30)
  .seconds(25);

bldr.hours();  // throws exception.  builder has no getters

var time = bldr.build();

time.hours(); // 5
time.hours(6); // throws, OR returns a clone

/*  A more explicit variant:  */
var bldr = moment.immutable()
  .setHours(5);

bldr.getHours; // undefined

var time = bldr.build();
time.getHours(); // 5
time.setHours;   // undefined
/* VALUE OBJECT */
var time = moment.immutable()   // 00:00:00
  .hours(5)       // new object => 05:00:00
  .minutes(30)    // new object => 05:30:00
  .seconds(25);   // new object => 05:30:25

/*  Same thing, but more efficient:  */
var time2 = moment.immutable(5,30,25); // 05:30:25

time.hours();   // 5
time.hours(6);  // new object => 06:30:25

Das erste Beispiel ist sehr Java-ähnlich, lässt aber auch wenig Unklarheit darüber, wie Momente aufgebaut sind und was man mit ihnen machen kann. Es bietet auch einen effizienten und intuitiven Weg, um mit geringem Aufwand neue Momente zu konstruieren, und folgt genau der Art und Weise, wie die meisten Menschen Moment verwenden.

Ich wäre dafür, dass Setter für erstellte Momente Ausnahmen auslösen, da dieses Verhalten die Mehrdeutigkeit weiter reduzieren würde (auf Kosten der Ausführlichkeit) und die Entwickler zwingen würde, jedes Mal, wenn sie neue Momente erstellen, zu bestätigen.

Das zweite Beispiel scheint viel mehr Aufwand zu haben, da wir viele Objekte erstellen (und verwerfen). Aber es gibt viel Raum für Optimierung. Moderne GC ist ziemlich gut; faule Bewertung könnte helfen; wir könnten Moment-Objekte so einfach wie möglich machen (wobei die zugrunde liegenden Date ), usw. (Für einige Vergleiche ist dieses Muster nicht unähnlich der Art und Weise, wie Strings in JavaScript behandelt werden)


Ich bin ein Fan von semver, aber der Anwendungsfall des Browsers macht Breaking Changes problematisch, da es ohne Modul-Loader unmöglich sein wird, zwei Versionen von moment auf derselben Seite zu haben.

Wie bereits erwähnt, gibt es eine Menge Legacy-Code, der von Moment abhängt. Zumindest brauchen wir eine Version, die beide Muster unterstützt, um eine reibungslose Übergangszeit zu ermöglichen.

+1 für Composable-Methoden, die neue Momente zurückgeben. Es ist mir egal, ob sie unveränderlich sind. Geben Sie mir einfach eine Komposition, damit ich Methoden verketten oder den mutierten Moment in einer Zeile (anstelle von 2) zuweisen kann.

@alexyuly warum funktioniert das Klonen bei dir nicht? Wenn Sie Inline komponieren möchten, können Sie Folgendes tun:

var a = moment();
var b = a.clone().subtract(1, 'week').startOf('day');

Oder Wasauchimmer.

@maggiepint Nun, ich fühle mich dumm, es sieht so aus, als könntest du die ganze Zeit Methoden komponieren. Danke für den Tipp. Vielleicht in den Dokumenten etwas klarer machen? zB http://momentjs.com/docs/#/manipulating/start -of/ <- kein Rückgabewert erwähnt.

Kleines Update - dieser Blogpost ist MEINE Position zu diesem Thema zu diesem Zeitpunkt: https://maggiepint.com/2016/06/24/why-moment-js-isnt-immutable-yet/

Ich spreche nicht für den Rest des Teams, aber sie haben es gesehen, und ich würde im Allgemeinen sagen, dass wir alle an einem ähnlichen Ort sind.

@maggiepint tolle und sehr gültige Punkte

Danke dafür. Unveränderlichkeit ist König in Redux, also werde ich auf jeden Fall zu js-joda wechseln. Ich kann immer noch einen Moment für die relative Zeit behalten.

Eric Lau - Google Mail

Am Freitag, den 24. Juni 2016 um 11:12 -0700 schrieb "Maggie Pint" [email protected] :

Kleines Update - dieser Blogpost ist MEINE Position zu diesem Thema zu diesem Zeitpunkt: https://maggiepint.com/2016/06/24/why-moment-js-isnt-immutable-yet/

Ich spreche nicht für den Rest des Teams, aber sie haben es gesehen, und ich würde im Allgemeinen sagen, dass wir alle an einem ähnlichen Ort sind.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Einige weitere typische Fehler/Verwirrung durch Mutation: http://stackoverflow.com/questions/26131003/moment-js-start-and-end-of-given-month

+1 dafür, aber bei Redux habe ich festgestellt, dass dies ein überraschend kleines Problem ist, da ich Moment-Instanzen überhaupt nicht in das Redux-Zustandsobjekt einfüge. Nur die Datumszeichenfolgen oder Zeitstempel und ich verwende Moment in den Rendermethoden, um die Datumszeichenfolgen in andere Zeichenfolgen zu konvertieren.

Ich tue dies hauptsächlich, weil es dann einfach ist, den Zustand ohne zusätzlichen Aufwand zu serialisieren und zu deserialisieren, aber es verbirgt auch die Mutation gut vor React und Redux.

Ich tue mein Bestes, um euch dieses Wochenende ein Update zu diesem Thema zu geben. Wir haben einen Plan, aber ich muss sicherstellen, dass alles funktioniert, bevor ich mich darauf verpflichte. Leider ziehe ich nächste Woche von Minneapolis nach Seattle, daher kann sich dies eine Zeit lang verlangsamen, aber ich möchte es voranbringen.

Kleines Update in Vorbereitung auf ein größeres Update, da ich festgestellt habe, dass dieser Blogpost immer noch etwas Traffic bekommt. Ich überarbeite derzeit den Build von Babel, um Babel zu verwenden. Dies bringt uns dazu, das Plugin von @butterflyhug in das Kern-Repository @butterflyhug hat uns sehr

@maggiepint planen Sie, während Sie Frozen-Moment offiziell unterstützen, https://github.com/WhoopInc/frozen-moment/issues/20 zu adressieren

Ich denke, dass dieser Ansatz zur Unveränderlichkeit gut genug ist, solange jeder Aufruf von moment() standardmäßig einen eingefrorenen Moment zurückgibt und Entwickler sich nicht daran erinnern müssen, jedes Mal .freeze() aufzurufen.

@gabrielmaldi Gute Frage. Ich schreibe den RFC (sollte jetzt jeden Tag fertig werden), und ja, es ist mein ausdrückliches Ziel, eine bessere Geschichte für den unveränderlichen Gebrauch bereitzustellen. Mein Vorschlag entspricht meinem Kommentar zu WhoopInc/frozen-moment#20 unter Berücksichtigung statischer Methoden. Ich werde hier und in dieser Ausgabe einen Link zu meinem RFC veröffentlichen, wenn ich meine PR gegen das RFC-Repo öffne, und wir würden uns sicherlich zu diesem Zeitpunkt über Feedback der Community zu dem Vorschlag freuen.

Ich habe den RFC-Entwurf fertig geschrieben und eine PR geöffnet .

Es ist ein ziemlich langes Dokument, zum Teil, weil noch einige Fragen offen sind, wie wir diese Funktionalität den Benutzern bereitstellen wollen, und deshalb versuche ich, die Vor- und Nachteile verschiedener Ansätze aufzuzeigen. Aber ich denke, die Implementierungsideen sind ziemlich solide, daher würde ich mich freuen, von Leuten hier zu hören, wenn Sie Vorbehalte gegenüber der vorgeschlagenen benutzerorientierten API haben .

Zusammenfassung von RFC mit unseren wichtigsten Fragen, die beantwortet werden müssen: https://maggiepint.com/2016/07/16/immutability-its-happening/

@maggiepint Ich habe versucht, einen Kommentar zu diesem Artikel zu posten, aber aus irgendeinem Grund wurde er verschluckt. Folgendes habe ich geschrieben:


Meine größte Sorge bei diesen Änderungen ist, dass sie auf einen unverhältnismäßig lautstarken und ausdrucksstarken Teil der Community reagieren – und das stille Bollwerk gewöhnlicher Entwickler vermeiden, die nicht einmal wissen, dass diese Diskussion stattfindet.

Die Threads von GitHub sind kein Mikrokosmos der breiteren Entwickler-Community. Diese Site leidet unter dem gleichen Partizipationsbias wie viele Foren im Internet und ist auf eine bestimmte Art von Entwicklern ausgerichtet: intellektuell mit der Computertheorie beschäftigt; Interesse an Ideen statt Anwendungen; und ich wage sogar zu sagen, dass sie gesellschaftlich geneigt sind, sich um beliebte Trends zu scharen. Diese Entwickler fühlen sich natürlich von philosophischen Célèbres wie Unveränderlichkeit und funktionaler Programmierung angezogen und haben näheren Zugang zu Ihnen als jede andere Gruppe. Sie werden die lauteste Stimme im Raum sein und nach dieser Veränderung schreien – aber was ist mit der Welt?

Die Welt will Stuff That Works. Es möchte wissen, dass die derzeit verwendete Bibliothek weiterhin Updates erhält - zumindest Bugfixes, aber idealerweise kleine inkrementelle Verbesserungen, die ihr Leben verbessern. Aber sie sagt es nicht, weil sie diese Foren nicht aktiv aufsucht und weil es eine dicke Haut braucht, um sich gegen den Trend auszusprechen.

Wenn Sie diese Änderung beabsichtigen, müssen Sie diesen Menschen meiner Meinung nach sehr deutlich machen, warum diese Änderung ihr Leben verbessern wird; warum sie aufrüsten sollten; warum sie sich keine Sorgen machen müssen, dass ihre Legacy-Projekte keine indirekten Bugfixes erhalten; und im Wesentlichen - was sie jetzt tun können, was sie derzeit nicht können.

Ich denke auch, dass Sie sehr vorsichtig sein sollten, um die Bedeutung dieser Änderung in realen Zahlen zu überprüfen. Ich frage mich, ob Sie diese Änderung als Plugin oder Wrapper veröffentlichen und ihre Aufnahme über mehrere Monate sorgfältig überwachen sollten, bevor Sie sie in den Trunk einbinden. Wenn Unveränderlichkeit als Nischenproblem überrepräsentiert wurde, haben Sie einen Weg gefunden, diese Sprachbenutzer zufrieden zu stellen, ohne den Verlauf der Bibliothek als Ganzes zu ändern.

Als Erstbenutzer habe ich hier nach einiger Zeit verloren mit startOf endOf geendet. Diese Methoden mutieren überraschenderweise!

+1 für volle Unveränderlichkeit

Vielleicht besteht eine andere Lösung darin, schmerzlich deutlich zu machen

Eine andere Lösung: Wenn Sie Veränderlichkeit wünschen, verwenden Sie objektorientierte Konzepte und erstellen Sie eine Objekterstellung mit dem Schlüsselwort NEW vs. dem Fabrikmuster moment().

Die Welt will Stuff That Works.
...Sie müssen diesen Menschen sehr deutlich machen, warum diese Veränderung ihr Leben verbessern wird

Jeder, den ich erlebt habe, dass er neu im Moment ist, tappt in die Falle, dass "Momente" mutiert werden.
Selbst nach 3 Jahren im Moment muss ich mir immer noch sagen "oh shit du verwendest .startOf hier .. schau lieber zweimal nach, ob du eine Kopie brauchst".

Das aktuelle Verhalten ist nicht intuitiv und das ist längst überfällig.
Versuchen Sie, array.filter/map mutieren zu lassen und sehen Sie, wie viel Spaß das macht.

Bezüglich...
Leistung/Speicher: Ich habe noch nie mehr als 2 Funktionen verkettet und normalerweise sind es .set().get()
Pseudo-Unveränderlichkeit: Es wird viele, viele Generationen dauern, bis das java-pass-by-ref-gen raus ist.

Ich mag die Idee von @AdamHess , zu entscheiden, ob Sie nach OOP oder Unveränderlichkeit suchen.

Meine zwei Cent darüber, warum wir verwirrt sind, ist Folgendes: Rückgabewerte. Wenn moment.add('1', 'days') undefiniert zurückgeben würde, wie dies bei veränderlichen Funktionen in JS im Allgemeinen der Fall ist, würde die Verwirrung verschwinden. Das gleiche Objekt zurückzugeben bedeutet zumindest für mich, dass ich eine neue Kopie habe. Das würde natürlich die Kettenfähigkeit zerstören.

Ich denke, es besteht eine geringe Wahrscheinlichkeit, dass bei mehr Entwicklern Probleme mit der Speichernutzung auftreten (außer bei speziellen Anwendungsfällen). Die Wandlungsfähigkeit von Moment hat mich jedoch schon gebissen. Datumsangaben sollten als Werte wie eine Zeichenfolge oder Zahl behandelt werden.

+1 für unveränderlich standardmäßig

Das gleiche Problem besteht übrigens für PHP. Willst du wie PHP sein?! 😆

In PHP lösen sie es, indem sie DateTimeImmutable (zusätzlich zu den normalen DateTime ) bereitstellen.

Wenn wir das Standardverhalten nicht so ändern, dass es unveränderlich ist, sollten wir zumindest eine erstklassige alternative API wie imoment / momenti (oder was auch immer) in Betracht ziehen. Ich würde das jedoch buchstäblich immer verwenden (über die veränderliche API) und ich würde hoffen, dass jede andere Bibliothek, die ich verwenden würde, auch die unveränderliche Version / API verwenden würde.

Ich stimme auch für Unveränderlichkeit, ich bin bereit, bei der Umsetzung zu helfen, wenn dies der Plan ist. Ich bin bereits bei der Addition und Subtraktion auf Veränderlichkeitsprobleme gestoßen, was es noch verwirrender macht, ist, dass diese Methoden die Instanz aufgrund der Verkettung zurückgeben.

Übrigens, wie sieht es mit der Klondauer aus? Was ist der beste Weg, das zu tun, konnte keine finden, die sich nicht hacky anfühlte.

@ngerritsen Ich glaube, die beste verfügbare Option ist moment.duration(existingDuration) .

Betreff: Umsetzung, #3548 ist immer noch eine aktive PR. Hoffentlich bleibt nicht mehr viel Arbeit auf Codeebene, aber es schadet nie, mehr Augen zu haben, um große Änderungen zu validieren. Wir müssen auch an der Dokumentation usw. arbeiten, bevor wir eine größere Versionsverbesserung durchführen können, die erforderlich ist, um eine Änderung wie diese zu veröffentlichen. Wenn Sie bei einer dieser Listen helfen möchten, würden wir uns freuen. 😀

Ich habe gerade eine Stunde damit verbracht, einen subtilen Fehler zu identifizieren, der durch die Mutation des ursprünglichen Datums durch .startOf() verursacht wurde ... Danke für die harte Arbeit, momentjs hat großartige Arbeit geleistet und gezeigt, wie man eine ausgezeichnete Datumsbibliothek für JS erstellt, aber ich wechsele zu date-fns wegen der sehr subtilen Natur dieser Art von Fehlern und weil ich nach meiner Einführung in einige allgemeine FP-Konzepte (hauptsächlich dank React, Redux und ELM) begann, die allgemeinen Vorteile der Unveränderlichkeit zu schätzen.

Für das, was es wert ist, hat lodash mit lodash/fp bereits einen eher FP-Ansatz verfolgt. Ich würde vorschlagen, einen Blick darauf zu werfen, wie lodash/fp implementiert wurde, da sie ihre vorhandenen Funktionen umschließen, anstatt alles komplett neu schreiben zu müssen. Lodash-Leute sind auch sehr besorgt über die Leistung.

Ich stimme auch @mull zu , das eigentliche Problem liegt für mich an der Verkettungs-API, die IMO nicht nur in diesem Fall, sondern allgemeiner (zB jQuery) einige große Designfehler aufweist. Ich wäre besser für mich, wenn Methoden-Mutationsdaten undefiniert zurückgeben würden (zumindest ist dies die allgemeine Regel, die ich auf den Code anwende, den ich schreibe).

Während der Namespace moment.frozen in Arbeit ist, würde ich - wie vom vorherigen Poster vorgeschlagen - empfehlen, nur date-fns zu verwenden .

Gerade einen weiteren Fehler aufgrund veränderlicher Momente behoben 🎉

Tangential verwandt wäre es großartig, wenn 3.0 in die ES6-Klassen übergehen könnte:

let mom1 = new Moment();
let mom2 = Moment.parse('2019-03-01T14:55');
// etc

Ein solcher Schritt könnte auch die Unveränderlichkeitsdiskussion leiten. Ich würde sagen, dass alle Methoden mit einer Ausnahme unveränderlich sein sollten. Eine Methode namens .set('minute/hour/year/etc', 18) .

Ich habe gerade angefangen, Moment zu verwenden, und war _entsetzt_, dass diese Bibliothek nicht von Anfang an völlig unveränderlich war. Ich verwende moment-unveränderlich, bis dies behoben wird.

Der @alancnet- Moment wird sich wahrscheinlich nie ändern. Es ist eine zu große Veränderung und es gibt genug Zurückdrängung von Benutzern, die gelernt haben, das aktuelle Verhalten zu akzeptieren.

Schauen Sie sich ihr neues Projekt an: luxon
Es ist sehr schön, modern, unveränderlich(!) und sollte viel besser funktionieren als moment-unveränderlich, das einfach alles in .clone() Aufrufe verpackt.

Für diejenigen, die von momentjs zu einem modernen Ansatz wechseln möchten, besuchen Sie bitte https://github.com/you-dont-need/You-Dont-Need-Momentjs

Sehr überrascht, dass es veränderbar ist!

Wie weit ist Luxon davon entfernt, ein Ersatz zu sein? Einer der Gründe, warum ich Moment.js verwende, ist die Zeitzonenunterstützung - sie ist ein Muss für mein Projekt.

@alamothe Diese Frage wird auf der Website eindeutig beantwortet: https://moment.github.io/luxon/docs/manual/moment.html

Schließen Sie dies. Wie andere bereits erwähnt haben, verwenden Sie Luxon, wenn Sie eine weitgehend unveränderliche API wünschen. Vielen Dank.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen