moment.jsの可変性を回避するにはどうすればよいですか?


106

モーメントオブジェクトの初期値を保存する必要があるという問題に遭遇しましたが、元のオブジェクトと一緒に変数が変更されないようにするのに問題があります。

残念ながら、Object.freeze()は機能しません。moment.jsがフォーマットしようとすると、「無効な日付」エラーが返されるためです。


3
そして、コードは次のようになります...?初期値を保存する場合は、valueOfメソッドまたは暗黙的な数値変換を使用して利用できる時間値を保存します。
RobG 2015年

あなたの変数が設定されると、それがセットされ、それはそうではなく何度も何度もそれを設定しないように見て、自動的に変更する文句を言わない
ジョン・スミス

回答:


184

NPMにはfrozen-momentというMoment.jsプラグインがあります-のmoment().freeze()代わりに使用できますObject.freeze(moment())

それ以外の場合、vanilla Moment.jsには、可変clone性の問題を回避するのに役立つメソッドがあるため、次のようなことができます。

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

更新:

この回答を書いてから2年になります。今回、日付を処理するための別のライブラリが浮上し、多くの注目を集めました:https : //date-fns.org/

このライブラリはデフォルトでは不変であり、モジュール式の機能的なアーキテクチャーに準拠しています。つまり、ツリーのシェイクやクライアント側のバンドリングに適しています。クライアント側でWebpackを多用するプロジェクトに取り組んでいて、Moment.jsがビルドに問題を引き起こしている場合、またはMoment.jsの可変性が原因で多くの問題が発生している場合でも、date-fns試してみる必要があります。


さて、fullCalendarプラグインでmoment.jsを使用していますが、予定よりも後のイベントの状態から瞬間のオブジェクトデータを取得していることがわかりました。可変性の問題は、moment.jsの問題ですが、提案をありがとうございました。時間を無駄にして申し訳ありません。
Shengbo1618

24
あなたは、保存された操作が可能moment:ちょうど使用クローン()このように:それを変異させずに、変数zz = moment(); zz.clone().add(3, 'h').toISOString();
Quake1TF

5
date-fnsのタイムゾーンサポートは非​​常に貧弱で、UTC日付はサポートされていないことに注意してください。
mjuopperi

3
私はdate-fnsしばらく使用してきましたが、Momentとboyを使用してレガシーコードにジャンプする必要がありました。この投稿により、ウィンドウからジャンプする必要がなくなりました。
Yuschick

dayjs不変の性質を持つMoment.jsと同様のAPIを備えているため、これも優れた代替手段です。(2019年3月現在、タイムゾーンのサポートはありませんが、これはかなり新しいライブラリであり、作業が進行中であることを確認できます。)
青田智行

2

これは私の意図ではないので、恥知らずな自己宣伝のための古い質問と謝罪です。それが誰かを助けることを願っています。

razorbeardの発言(.clone()など)に加えて、Moment.jsに付属しているものに不変のメソッドを追加するNPMモジュールを作成しました。意図は既存のコードを壊すことではないので、モジュールはImmuその名前に追加された新しいメソッドを追加します。

モーメントファクトリによって返される各インスタンスは、不変のメソッドで装飾されます。たとえば、moment().startOf()対応するstartOfImmu()add()があるaddImmu()などです。これらの各インスタンスは、既存のモーメントを変更するのではなく、新しいモーメントを返します。これを使用するには、momentファクトリをmomentImmutableMethodsに渡して、新しい不変メソッドにアクセスします。例:

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"

https://www.npmjs.com/package/moment-immutable-methodsの NPMにあります

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.