Javascript 如何处理moment.js中的易变性?

Javascript 如何处理moment.js中的易变性?,javascript,object,immutability,momentjs,mutability,Javascript,Object,Immutability,Momentjs,Mutability,我遇到了一个问题,我必须存储力矩对象的初始值,但我在阻止变量随原始对象更改时遇到了一些问题 不幸的是Object.freeze()不起作用,因为当我尝试格式化时,moment.js返回一个“无效日期”错误。NPM上有一个名为moment.js的插件-你可以使用moment().freeze()代替Object.freeze(moment()) 否则,vanilla Moment.js有一个clone方法可以帮助您避免可变性问题,因此您可以这样做: var a = moment(), b

我遇到了一个问题,我必须存储力矩对象的初始值,但我在阻止变量随原始对象更改时遇到了一些问题


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

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

否则,vanilla Moment.js有一个
clone
方法可以帮助您避免可变性问题,因此您可以这样做:

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

我写这个答案已经两年了。在这段时间里,另一个用于处理日期的库浮出水面,并获得了很大的吸引力:


该库在默认情况下是不可变的,并且遵循模块化、功能化的体系结构,这意味着它更适合于树抖动和客户端绑定。如果您正在从事一个在客户端大量使用Webpack的项目,并且发现Moment.js给您的构建带来了麻烦,或者即使Moment.js的易变性给您带来了很多麻烦,那么您应该尝试一下
date fns

这是一个老生常谈的问题,我为无耻的自我推销道歉,因为这不是我的本意,只是希望它能帮助别人

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

矩工厂返回的每个实例都将使用不可变的方法进行修饰,例如
moment()。startOf()
将有相应的
startofimum()
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的

上,您也可以使用这个库,它几乎拥有与moment.js完全相同的API,但它是不可变的。

代码看起来像…?如果要存储初始值,请存储时间值,可使用valueOf方法或隐式转换为数字。一旦设置了变量,它将不会自动更改,因此最好不要再次设置,我在fullCalendar插件中使用了moment.js,结果证明我是从比预期更晚的事件状态中获取了moment对象数据。不过,moment.js肯定存在易变性问题,所以非常感谢您的建议,很抱歉我浪费了您的时间。您可以操作存储的
moment
变量,而无需对其进行变异:只需像这样使用clone():
zz=moment();添加(3,'h').toISOString()
注意date fns的时区支持非常差,而且不支持UTC日期。我已经使用了
date fns
一段时间了,但后来不得不使用Moment and boy跳入旧式代码,这篇文章让我免于跳出窗口吗。也是一个很好的选择,因为它的API类似于Moment.js,具有不可变的特性。(截至2019年3月,它缺少时区支持,但这是一个相当新的库,我可以观察到这项工作正在进行。)