web-dev-qa-db-fra.com

Comment puis-je contourner la mutabilité dans moment.js?

J'ai rencontré un problème où je devais stocker les valeurs initiales d'un objet moment mais j'ai quelques problèmes pour empêcher ma variable de changer en même temps que l'objet d'origine.

Malheureusement, Object.freeze () ne fonctionne pas, car moment.js renvoie l'erreur "Date invalide" lorsque j'essaie de formater cela.

72
Shengbo1618

Il existe un plugin Moment.js sur NPM appelé frozen-moment - Vous pouvez utiliser moment().freeze() à la place de Object.freeze(moment()).

Sinon, Vanilla Moment.js utilise une méthode clone qui devrait vous aider à éviter les problèmes de mutabilité, afin que vous puissiez faire quelque chose comme ceci:

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

METTRE À JOUR:

Cela fait deux ans que j'ai écrit cette réponse. Pendant ce temps, une autre bibliothèque pour travailler avec les dates a fait surface et a gagné beaucoup de traction: https://date-fns.org/

Cette bibliothèque est immuable par défaut et suit une architecture fonctionnelle modulaire, ce qui la rend plus adaptée aux secousses d’arbres et au groupage côté client. Si vous travaillez sur un projet qui utilise beaucoup Webpack côté client et que vous trouvez que Moment.js vous pose des problèmes de construction, ou même si la mutabilité de Moment.js vous cause beaucoup de maux de tête, devrait donner date-fns un essai. 

125
razorbeard

C'est une vieille question et des excuses pour une auto-promotion éhontée, car ce n'est pas mon intention, espérons que cela aidera quelqu'un.

En plus de ce que dit razorbeard (.clone() etc.), j'ai créé un module NPM qui associe des méthodes immuables à tout ce que Moment.js est livré avec, tout de suite. L'intention n'est pas de casser le code existant afin que le module ajoute de nouvelles méthodes avec Immu ajouté à son nom.

Chaque instance renvoyée par moment factory sera décorée avec des méthodes immuables. Par exemple, moment().startOf() aura la fonction correspondante startOfImmu(), add() aura la fonction addImmu() etc. Pour l'utiliser, il suffit de passer de moment factory à momentImmutableMethods pour avoir accès à de nouvelles méthodes immuables. Exemple:

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"

C'est sur NPM à https://www.npmjs.com/package/moment-immutable-methods

0
spirytus

Vous pouvez également utiliser le paquetage figé-instantané si vous aimez un code plus immuable.

0
morhook