Bagaimana cara mengatasi mutabilitas di moment.js?


107

Saya mengalami masalah di mana saya harus menyimpan nilai awal objek momen tetapi saya mengalami masalah mencegah variabel saya berubah seiring dengan objek aslinya.

Sayangnya Object.freeze () tidak berfungsi, karena moment.js mengembalikan kesalahan "Invalid date" ketika saya mencoba memformatnya.


3
Dan kodenya terlihat seperti…? Jika Anda ingin menyimpan nilai awal, simpan nilai waktu, tersedia menggunakan metode valueOf atau konversi implisit ke angka.
RobG

setelah variabel Anda disetel, itu disetel, itu tidak akan berubah secara otomatis, jadi lihatlah untuk tidak menyetelnya lagi dan lagi
john Smith

Jawaban:


185

Ada plugin Moment.js di NPM yang disebut momen beku - Anda dapat menggunakannya moment().freeze()sebagai pengganti Object.freeze(moment()).

Jika tidak, vanilla Moment.js memiliki clonemetode yang akan membantu Anda menghindari masalah mutabilitas, jadi Anda dapat melakukan sesuatu seperti ini:

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

MEMPERBARUI:

Sudah dua tahun sejak saya menulis jawaban ini. Saat ini, perpustakaan lain untuk bekerja dengan tanggal telah muncul dan mendapatkan banyak daya tarik: https://date-fns.org/

Library ini tidak dapat diubah secara default dan mengikuti arsitektur modular fungsional, yang berarti lebih cocok untuk pengocokan pohon dan bundling sisi klien. Jika Anda sedang mengerjakan proyek yang menggunakan Webpack secara ekstensif di sisi klien, dan menemukan bahwa Moment.js memberi Anda masalah dengan build Anda, atau bahkan jika mutabilitas Moment.js membuat Anda sangat pusing, maka Anda harus date-fnsdicoba.


Nah, saya menggunakan moment.js di plugin fullCalendar dan ternyata saya mendapatkan data objek momen dari status acara saya nanti daripada yang seharusnya. Masalah mutabilitas jelas merupakan masalah dengan moment.js, jadi terima kasih banyak atas sarannya dan maaf saya menyia-nyiakan waktu Anda.
Shengbo1618

24
Anda dapat memanipulasi momentvariabel yang disimpan tanpa memutasinya: cukup gunakan clone () seperti ini:zz = moment(); zz.clone().add(3, 'h').toISOString();
Quake1TF

5
Perhatikan bahwa date-fns memiliki dukungan zona waktu yang sangat buruk dan tidak ada dukungan untuk tanggal UTC.
mjuopperi

3
Saya telah menggunakan date-fnsuntuk sementara waktu sekarang tetapi sejak itu harus melompat ke kode warisan menggunakan Momen dan anak laki-laki, apakah posting ini menyelamatkan saya dari melompat keluar jendela.
Yuschick

dayjsjuga merupakan alternatif yang baik karena memiliki API yang mirip dengan Moment.js dengan sifat yang tidak berubah. (Mulai Maret 2019, tidak ada dukungan zona waktu tetapi ini adalah perpustakaan yang cukup baru dan saya dapat mengamati bahwa pekerjaan sedang berlangsung.)
Tomoyuki Aota

2

Ini pertanyaan lama dan permintaan maaf untuk promosi diri yang tidak tahu malu karena ini bukan niat saya, hanya berharap itu akan membantu seseorang.

Selain apa yang dikatakan razorbeard ( .clone()dll) saya membuat modul NPM yang melampirkan metode yang tidak dapat diubah ke apa pun yang dilengkapi dengan Moment.js di luar kotak. Tujuannya bukan untuk merusak kode yang ada sehingga modul menambahkan metode baru denganImmu menambahkan namanya.

Setiap instance yang dikembalikan oleh pabrik saat akan didekorasi dengan metode yang tidak dapat diubah misalnya moment().startOf()akan memiliki yang sesuai startOfImmu(), add()akan memiliki, addImmu()dll. Masing-masing mengembalikan momen baru daripada memodifikasi yang sudah ada. Untuk menggunakannya, cukup lewati momentpabrik momentImmutableMethodsuntuk mendapatkan akses ke metode baru yang tidak dapat diubah. Contoh:

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"

Ada di NPM di https://www.npmjs.com/package/moment-immutable-methods

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.