我如何在moment.js中解决可变性问题?

时间:2022-04-28 21:30:45

I've run into a problem where I have to store the initial values of a moment object but I'm having some trouble preventing my variable from changing along with the original object.

我遇到了一个问题,我必须存储一个时刻对象的初始值,但是我遇到了一些问题,我不能防止我的变量与原始对象一起变化。

Unfortunately Object.freeze() doesn't work, because moment.js returns an "Invalid date" error when I try to format that.

不幸的是,Object.freeze()不起作用,因为当我尝试格式化时,moment.js返回“无效日期”错误。

2 个解决方案

#1


82  

There's a Moment.js plugin on NPM called frozen-moment - You could use moment().freeze() in place of Object.freeze(moment()).

在NPM上有一个名为frozen-moment的Moment.js插件 - 你可以使用moment()。freeze()代替Object.freeze(moment())。

Otherwise, vanilla Moment.js has a clone method that should help you avoid mutability problems, so you could do something like this:

否则,vanilla Moment.js有一个克隆方法可以帮助你避免可变性问题,所以你可以这样做:

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

UPDATE:

更新:

It has been two years since I wrote this answer. In this time, another library for working with dates has surfaced and gained a lot of traction: https://date-fns.org/

我写这个答案已经两年了。在这个时候,另一个处理日期的图书馆浮出水面并获得了很大的吸引力:https://date-fns.org/

This library is immutable by default and follows a modular, functional architecture, which means it is better suited to tree shaking and client-side bundling. If you are working on a project that makes extensive use of Webpack on the client side, and find that Moment.js is giving you trouble with your build, or even if Moment.js' mutability is causing you a lot of headache, then you should give date-fns a try.

该库默认是不可变的,遵循模块化的功能架构,这意味着它更适合树摇动和客户端捆绑。如果您正在开发一个在客户端广泛使用Webpack的项目,并且发现Moment.js给您的构建带来麻烦,或者即使Moment.js的可变性让您头疼,那么您应该尝试一下日期。

#2


0  

It's an old question and apologies for shameless self promotion as this is not my intention, just hope it will help someone.

这是一个古老的问题,并为无耻的自我推销道歉,因为这不是我的意图,只是希望它会帮助某人。

In addition to what razorbeard says (.clone() etc) I created NPM module that attaches immutable methods to whatever Moment.js comes with out of the box. The intention is not to break existing code so module adds new methods with Immu appended to its name.

除了razorbeard所说的(.clone()等)之外,我创建了NPM模块,它将不可变方法附加到开箱即用的Moment.js中。目的不是破坏现有代码,因此模块添加了新的方法,并在其名称后附加了Immu。

Each instance returned by moment factory will be decorated with immutable methods e.g moment().startOf() will have corresponding startOfImmu(), add() will have addImmu() etc. Each of those returns new moment rather then modifying existing one. To use it just pass moment factory to momentImmutableMethods to get access to new immutable methods. Example:

由moment工厂返回的每个实例都将使用不可变的方法进行修饰,例如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"

Its on NPM at https://www.npmjs.com/package/moment-immutable-methods

它在NPM上的https://www.npmjs.com/package/moment-immutable-methods

#1


82  

There's a Moment.js plugin on NPM called frozen-moment - You could use moment().freeze() in place of Object.freeze(moment()).

在NPM上有一个名为frozen-moment的Moment.js插件 - 你可以使用moment()。freeze()代替Object.freeze(moment())。

Otherwise, vanilla Moment.js has a clone method that should help you avoid mutability problems, so you could do something like this:

否则,vanilla Moment.js有一个克隆方法可以帮助你避免可变性问题,所以你可以这样做:

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

UPDATE:

更新:

It has been two years since I wrote this answer. In this time, another library for working with dates has surfaced and gained a lot of traction: https://date-fns.org/

我写这个答案已经两年了。在这个时候,另一个处理日期的图书馆浮出水面并获得了很大的吸引力:https://date-fns.org/

This library is immutable by default and follows a modular, functional architecture, which means it is better suited to tree shaking and client-side bundling. If you are working on a project that makes extensive use of Webpack on the client side, and find that Moment.js is giving you trouble with your build, or even if Moment.js' mutability is causing you a lot of headache, then you should give date-fns a try.

该库默认是不可变的,遵循模块化的功能架构,这意味着它更适合树摇动和客户端捆绑。如果您正在开发一个在客户端广泛使用Webpack的项目,并且发现Moment.js给您的构建带来麻烦,或者即使Moment.js的可变性让您头疼,那么您应该尝试一下日期。

#2


0  

It's an old question and apologies for shameless self promotion as this is not my intention, just hope it will help someone.

这是一个古老的问题,并为无耻的自我推销道歉,因为这不是我的意图,只是希望它会帮助某人。

In addition to what razorbeard says (.clone() etc) I created NPM module that attaches immutable methods to whatever Moment.js comes with out of the box. The intention is not to break existing code so module adds new methods with Immu appended to its name.

除了razorbeard所说的(.clone()等)之外,我创建了NPM模块,它将不可变方法附加到开箱即用的Moment.js中。目的不是破坏现有代码,因此模块添加了新的方法,并在其名称后附加了Immu。

Each instance returned by moment factory will be decorated with immutable methods e.g moment().startOf() will have corresponding startOfImmu(), add() will have addImmu() etc. Each of those returns new moment rather then modifying existing one. To use it just pass moment factory to momentImmutableMethods to get access to new immutable methods. Example:

由moment工厂返回的每个实例都将使用不可变的方法进行修饰,例如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"

Its on NPM at https://www.npmjs.com/package/moment-immutable-methods

它在NPM上的https://www.npmjs.com/package/moment-immutable-methods