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

How do I work around mutability in moment.js?

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

不幸的是 Object.freeze() 不起作用,因为 moment.js returns 当我尝试格式化时出现 Invalid date 错误。

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

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

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

更新:

写这个答案已经两年了。在此期间,另一个用于处理日期的库浮出水面并获得了很大的关注:https://date-fns.org/

这个库默认是不可变的,遵循模块化的功能架构,这意味着它更适合 tree shaking 和客户端捆绑。如果您正在从事一个在客户端广泛使用 Webpack 的项目,并且发现 Moment.js 给您的构建带来了麻烦,或者即使 Moment.js' 的可变性给您带来了很多麻烦头疼,那么你应该date-fns试一试。

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

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

moment factory 返回的每个实例都将使用不可变方法进行修饰,例如 moment().startOf() 将具有相应的 startOfImmu()add() 将具有 addImmu() 等。每个 returns 新时刻而不是修改现有时刻。要使用它,只需将 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 上

您还可以使用 day.js 库,它具有几乎与 moment.js 完全相同的 API,但不可变。