Come aggirare la mutabilità in moment.js?


107

Ho riscontrato un problema in cui devo memorizzare i valori iniziali di un oggetto moment, ma ho qualche problema a impedire che la mia variabile cambi insieme all'oggetto originale.

Sfortunatamente Object.freeze () non funziona, perché moment.js restituisce un errore "Data non valida" quando provo a formattarlo.


3
E il codice sembra ...? Se si desidera memorizzare il valore iniziale, memorizzare il valore temporale, disponibile utilizzando il metodo valueOf o la conversione implicita in numero.
RobG

una volta che la tua variabile è impostata, è impostata, non cambierà automaticamente, quindi cerca di non impostarla più e più volte
John Smith

Risposte:


185

C'è un plug-in Moment.js su NPM chiamato frozen-moment , che potresti usare moment().freeze()al posto di Object.freeze(moment()).

Altrimenti, vanilla Moment.js ha un clonemetodo che dovrebbe aiutarti a evitare problemi di mutabilità, quindi potresti fare qualcosa del genere:

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

AGGIORNARE:

Sono passati due anni da quando ho scritto questa risposta. In questo periodo, è emersa un'altra libreria per lavorare con le date e ha guadagnato molta popolarità: https://date-fns.org/

Questa libreria è immutabile per impostazione predefinita e segue un'architettura modulare e funzionale, il che significa che è più adatta allo scuotimento degli alberi e al raggruppamento lato client. Se stai lavorando a un progetto che fa ampio uso di Webpack sul lato client e scopri che Moment.js ti sta dando problemi con la tua build, o anche se la mutabilità di Moment.js ti sta causando molto mal di testa, allora tu dovrebbe date-fnsprovare.


Bene, sto usando moment.js nel plugin fullCalendar e si scopre che stavo ottenendo i dati dell'oggetto del momento da uno stato successivo del mio evento rispetto a quanto avrei dovuto. I problemi di mutabilità sono sicuramente una cosa con moment.js, quindi grazie mille per il suggerimento e scusa se ho perso il tuo tempo.
Shengbo1618

24
Puoi manipolare la momentvariabile memorizzata senza modificarla: usa semplicemente clone () in questo modo:zz = moment(); zz.clone().add(3, 'h').toISOString();
Quake1TF

5
Nota che date-fns ha un supporto per il fuso orario molto scarso e non supporta le date UTC.
mjuopperi

3
Lo sto usando date-fnsda un po 'di tempo, ma da allora sono dovuto passare al codice legacy usando Moment and boy, questo post mi ha salvato dal saltare da una finestra.
Yuschick

dayjsè anche una buona alternativa poiché ha API simili a Moment.js con natura immutabile. (A partire da marzo 2019, manca il supporto per il fuso orario, ma questa è una libreria abbastanza nuova e posso osservare che il lavoro è in corso.)
Tomoyuki Aota

2

È una vecchia domanda e mi scuso per la spudorata autopromozione in quanto questa non è la mia intenzione, spero solo che possa aiutare qualcuno.

Oltre a ciò che dice razorbeard ( .clone()ecc.) Ho creato il modulo NPM che collega metodi immutabili a qualsiasi cosa Moment.js venga fornito immediatamente. L'intenzione non è quella di rompere il codice esistente, quindi il modulo aggiunge nuovi metodi con Immuaggiunto al suo nome.

Ogni istanza restituita da moment factory sarà decorata con metodi immutabili, ad esempio moment().startOf()avrà corrispondenti startOfImmu(), add()avrà addImmu()ecc. Ognuna di queste restituisce un nuovo momento piuttosto che modificare quello esistente. Per usarlo basta passare momentfactory a momentImmutableMethodsper avere accesso a nuovi metodi immutabili. Esempio:

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"

È su NPM su https://www.npmjs.com/package/moment-immutable-methods

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.