ฉันจะแก้ไขความไม่แน่นอนใน moment.js ได้อย่างไร


107

ฉันพบปัญหาที่ฉันต้องเก็บค่าเริ่มต้นของวัตถุชั่วขณะ แต่ฉันมีปัญหาในการป้องกันไม่ให้ตัวแปรของฉันเปลี่ยนไปพร้อมกับวัตถุดั้งเดิม

ขออภัย Object.freeze () ไม่ทำงานเนื่องจาก moment.js ส่งกลับข้อผิดพลาด "Invalid date" เมื่อฉันพยายามจัดรูปแบบ


3
และรหัสดูเหมือนว่า…? หากคุณต้องการจัดเก็บค่าเริ่มต้นให้เก็บค่าเวลาที่มีอยู่โดยใช้เมธอดvalueOfหรือการแปลงเป็นตัวเลขโดยปริยาย
RobG

เมื่อตั้งค่าตัวแปรของคุณแล้วมันจะไม่เปลี่ยนแปลงโดยอัตโนมัติดังนั้นอย่าตั้งค่าซ้ำแล้วซ้ำอีก
john Smith

คำตอบ:


185

มีปลั๊กอิน Moment.js บน NPM ที่เรียกว่าFrozen-moment - คุณสามารถใช้moment().freeze()แทนObject.freeze(moment())ไฟล์.

มิฉะนั้น vanilla Moment.js จะมีcloneวิธีการที่จะช่วยคุณหลีกเลี่ยงปัญหาความแปรปรวนดังนั้นคุณสามารถทำสิ่งนี้ได้:

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

อัพเดท:

เป็นเวลาสองปีแล้วที่ฉันเขียนคำตอบนี้ ในเวลานี้ห้องสมุดอื่นสำหรับการทำงานกับวันที่ปรากฏขึ้นและได้รับแรงฉุดมากมาย: https://date-fns.org/

ไลบรารีนี้ไม่เปลี่ยนรูปตามค่าเริ่มต้นและเป็นไปตามสถาปัตยกรรมแบบแยกส่วนที่ใช้งานได้ซึ่งหมายความว่าเหมาะสำหรับการเขย่าต้นไม้และการรวมฝั่งไคลเอ็นต์ หากคุณกำลังทำงานในโปรเจ็กต์ที่ใช้ Webpack อย่างกว้างขวางในฝั่งไคลเอ็นต์และพบว่า Moment.js กำลังทำให้คุณมีปัญหากับบิลด์ของคุณหรือแม้ว่าความไม่แน่นอนของ Moment.js จะทำให้คุณปวดหัวมากก็ตาม ควรdate-fnsลอง


ฉันใช้ moment.js ในปลั๊กอิน fullCalendar และปรากฎว่าฉันได้รับข้อมูลวัตถุช่วงเวลาจากเหตุการณ์ในภายหลังมากกว่าที่ฉันควรจะเป็น ปัญหาความไม่แน่นอนเป็นเรื่องของ moment.js ดังนั้นขอบคุณมากสำหรับคำแนะนำและขอโทษที่ทำให้คุณเสียเวลา
Shengbo1618

24
คุณสามารถจัดการmomentตัวแปรที่เก็บไว้ได้โดยไม่ต้องกลายพันธุ์เพียงใช้ clone () ดังนี้zz = moment(); zz.clone().add(3, 'h').toISOString();
Quake1TF

5
โปรดทราบว่า date-fns มีการรองรับเขตเวลาที่แย่มากและไม่มีการรองรับวันที่ UTC
mjuopperi

3
ฉันใช้date-fnsมาระยะหนึ่งแล้ว แต่หลังจากนั้นก็ต้องข้ามไปสู่รหัสเดิมโดยใช้ Moment and boy โพสต์นี้ช่วยฉันไม่ให้กระโดดออกไปนอกหน้าต่าง
Yuschick

dayjsยังเป็นทางเลือกที่ดีเนื่องจากมี API ที่คล้ายกับ Moment.js ที่มีลักษณะไม่เปลี่ยนรูป (ณ เดือนมีนาคม 2019 ไม่มีการรองรับเขตเวลา แต่นี่เป็นห้องสมุดใหม่ที่ค่อนข้างใหม่และฉันสังเกตได้ว่างานกำลังดำเนินอยู่)
Tomoyuki Aota

3

มันเป็นคำถามเก่า ๆ และขอโทษสำหรับการโปรโมตตัวเองที่ไร้ยางอายเพราะนี่ไม่ใช่ความตั้งใจของฉันแค่หวังว่ามันจะช่วยใครสักคน

นอกเหนือจากสิ่งที่ razorbeard พูด ( .clone()ฯลฯ ) ฉันได้สร้างโมดูล NPM ที่แนบวิธีการที่ไม่เปลี่ยนรูปเข้ากับ Moment.js ที่มาพร้อมกับกล่อง ความตั้งใจที่จะไม่ทำลายรหัสที่มีอยู่ดังนั้นโมดูลจึงเพิ่มวิธีการใหม่พร้อมกับ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"

บน NPM ที่https://www.npmjs.com/package/moment-immutable-methods

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.