Jak obejść zmienność w pliku moment.js?


107

Napotkałem problem polegający na tym, że muszę przechowywać wartości początkowe obiektu chwili, ale mam pewne problemy z zapobieganiem zmianie mojej zmiennej wraz z oryginalnym obiektem.

Niestety Object.freeze () nie działa, ponieważ moment.js zwraca błąd „Nieprawidłowa data”, gdy próbuję to sformatować.


3
A kod wygląda tak…? Jeśli chcesz zapisać wartość początkową, zapisz wartość czasu, dostępną za pomocą metody valueOf lub niejawnej konwersji na liczbę.
— RobG

kiedy twoja zmienna jest ustawiona, jest ustawiona, nie zmieni się automagicznie, więc raczej staraj się nie ustawiać jej raz po raz
— john Smith

Odpowiedzi:


185

W NPM jest wtyczka Moment.js o nazwie frozen-moment - możesz użyć moment().freeze()zamiast Object.freeze(moment()).

W przeciwnym razie vanilla Moment.js ma clonemetodę, która powinna pomóc ci uniknąć problemów ze zmiennością, więc możesz zrobić coś takiego:

var a = moment(),
    b = a.clone(); // or moment(a)

AKTUALIZACJA:

Minęły dwa lata, odkąd napisałem tę odpowiedź. W tym czasie pojawiła się kolejna biblioteka do pracy z datami i zyskała dużą popularność: https://date-fns.org/

Ta biblioteka jest domyślnie niezmienna i jest zgodna z modułową, funkcjonalną architekturą, co oznacza, że ​​lepiej nadaje się do wstrząsania drzewem i tworzenia pakietów po stronie klienta. Jeśli pracujesz nad projektem, który w znacznym stopniu wykorzystuje Webpack po stronie klienta i zauważysz, że Moment.js sprawia problemy z twoją kompilacją, a nawet jeśli zmienność Moment.js powoduje wiele bólu głowy, to powinien date-fnsspróbować.


Cóż, używam momentu.js we wtyczce fullCalendar i okazuje się, że otrzymywałem dane obiektu momentu z późniejszego stanu mojego zdarzenia niż powinienem. Problemy ze zmiennością są jednak zdecydowanie problemem w przypadku moment.js, więc bardzo dziękuję za sugestię i przepraszam, że zmarnowałem Twój czas.
— Shengbo1618

24
Możesz manipulować zapisaną momentzmienną bez jej mutowania: po prostu użyj clone () w ten sposób:zz = moment(); zz.clone().add(3, 'h').toISOString();
— Quake1TF

5
Zauważ, że date-fns ma bardzo słabą obsługę stref czasowych i nie obsługuje dat UTC.
— mjuopperi

3
Używam go już date-fnsod jakiegoś czasu, ale od tego czasu musiałem wskoczyć do starszego kodu za pomocą Moment and boy, czy ten post uratował mnie przed wyskoczeniem z okna.
— Yuschick

dayjsjest również dobrą alternatywą, ponieważ ma interfejsy API podobne do Moment.js z niezmiennym charakterem. (Od marca 2019 roku brakuje obsługi stref czasowych, ale jest to dość nowa biblioteka i widzę, że prace trwają.)
— Tomoyuki Aota

2

To stare pytanie i przeprosiny za bezwstydną autopromocję, ponieważ nie jest to moim zamiarem, mam tylko nadzieję, że komuś pomoże.

Oprócz tego, co mówi razorbeard ( .clone()itp.), Stworzyłem moduł NPM, który dołącza niezmienne metody do wszystkiego, co Moment.js jest dostarczane po wyjęciu z pudełka. Celem nie jest przerywanie istniejącego kodu, więc moduł dodaje nowe metody z Immudopiskiem do jego nazwy.

Każda instancja zwrócona przez chwilę fabryka będzie udekorowana niezmiennymi metodami, np. moment().startOf()Będzie miała odpowiednie startOfImmu(), add()będzie miała addImmu()itd. Każda z nich zwraca nowy moment zamiast modyfikować istniejący. Aby z niego skorzystać, wystarczy przejść przez momentfabrykę, momentImmutableMethodsaby uzyskać dostęp do nowych niezmiennych metod. Przykład:

var moment = require('moment'); // or moment-timezone 
import { momentImmutableMethods } from 'moment-immutable-methods';

// to decorate instances with immutable methods we need to extend moment factory as below:
momentImmutableMethods(moment);

// now every instance returned by moment will have Immu methods attached.


// IMMUTABLE EXAMPLE
// we using immutable methods that were attached to every instance, these have Immu appended to original name
const ddd = moment({
  hour: 5,
  minute: 10
});
// Moment {_isAMomentObject: true, _i: {…}, _isUTC: false, _pf: {…}, _locale: Locale, …}
const eee = ddd.startOfImmu('day');
// Moment {_isAMomentObject: true, _i: {…}, _isUTC: false, _pf: {…}, _locale: Locale, …}
console.log(ddd === eee);
// false
const fff = eee.startOfImmu('month');
// Moment {_isAMomentObject: true, _i: {…}, _isUTC: false, _pf: {…}, _locale: Locale, …}
console.log(ddd === fff);
// false
console.log(eee === fff);
// false
console.log(ddd.format('DD/MM/YY HH:mma'));
// "14/04/18 05:10am"
console.log(eee.format('DD/MM/YY HH:mma'));
// "14/04/18 00:00am"
console.log(fff.format('DD/MM/YY HH:mma'));
// "08/04/18 00:00am"

Jest na NPM pod adresem https://www.npmjs.com/package/moment-immutable-methods

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.