使用`Date.protype.toISOString`时,我可以去掉`.000Z`吗



我有一些数据表示为类X的对象。该对象的一些字段包含日期-标准内置Date构造函数的实例。

问题是,我需要使用Axios将类X的对象作为JSON字符串传递。当表示日期的字段转换为字符串时,会在它们上使用Date.prototype.toISOString。然而,它将字符串转换为以下格式:2017-11-14T06:22:43.000Z,-而我需要它们与几乎相同,但最后没有.000Z(服务器似乎不喜欢这样(。

我看到两个选项如何实现:

  1. 手动修改对象
    虽然听起来没有那么糟糕,但它有一些缺点:首先,实际上我没有一个X类的对象,而是有很多。可能是匈奴人。因此,就性能而言,这可能会成为一项相当昂贵的操作。第二件事是,我非常确信应该有一个更优雅的解决方案
  2. 增强Date.prototype.toISOString方法
    我试过这样做,但不知道这是否是一个好的决定(1(,我也不知道如何使它(2(成为方法首先调用自己(执行它必须执行的操作(,然后用substr修改它的输出的方式:会发生无休止的递归。看:

Date.prototype.toISOString = function(...args) {
const res = Date.prototype.toISOString(...args);
return res.substr(0, 19);
};
const date = new Date();
document.write(date.toISOString());

以下方式不起作用:

const originalMethod = Date.prototype.toISOString;
Date.prototype.toISOString = function(...args) {
const res = originalMethod(...args);
return res.substr(0, 19);
};
const date = new Date();
document.write(date.toISOString());
See the console. It outputs "Method Date.prototype.toISOString called on incompatible receiver undefined"

那么,为什么不起作用呢?更重要的是,解决我问题的最佳方法是什么?

为什么不起作用?

因为您调用的originalMethod没有this值。一个工作代码是

const originalMethod = Date.prototype.toISOString;
Date.prototype.toISOString = function(...args) {
const res = originalMethod.apply(this, args);
return res.substr(0, 19);
};

我不知道这是否是一个好的决定

不,绝对不是。不要干扰内置代码——代码的其他部分(或其依赖项(可能依赖于它们的正确功能。

解决问题的最佳方法是什么?

不要修改所有Date实例的toJSON行为,只修改X对象的序列化:

class X {
…
toJSON() {
return {
...this,
// TODO: fix backend to acccept standard timestamp formats
date: this.date.toISOString().replace(/(?:.d{1,3})?Z$/, ''),
…
};
}
}

您可以创建自己的替换器函数来与JSON.stringify()一起使用。您可以为任何日期添加特殊处理,但保留任何其他值不变:

function customReplacer(key, value) {
if (key === "") //initial object
return value;

if (this[key] instanceof Date) //any date
return value.slice(0, 19);

return value; //anything else
}
const obj = {
a: "hello world",
b: {
c: 42
},
d: [1, 2, 3],
e: new Date(),
f: {
g: true,
h: new Date(),
i: null
}
}
console.log(JSON.stringify(obj, customReplacer, 4))
.as-console-wrapper {
max-height: 100% !important;
}

请注意,value将是序列化值,而不是Date对象。因此,要获得初始的非串行化对象,需要获得this[key]——函数将使用当前串行化为this的对象进行调用。

相关内容

  • 没有找到相关文章

最新更新