我有一些数据表示为类X的对象。该对象的一些字段包含日期-标准内置Date
构造函数的实例。
问题是,我需要使用Axios将类X的对象作为JSON字符串传递。当表示日期的字段转换为字符串时,会在它们上使用Date.prototype.toISOString
。然而,它将字符串转换为以下格式:2017-11-14T06:22:43.000Z
,-而我需要它们与几乎相同,但最后没有.000Z
(服务器似乎不喜欢这样(。
我看到两个选项如何实现:
- 手动修改对象
虽然听起来没有那么糟糕,但它有一些缺点:首先,实际上我没有一个X类的对象,而是有很多。可能是匈奴人。因此,就性能而言,这可能会成为一项相当昂贵的操作。第二件事是,我非常确信应该有一个更优雅的解决方案 - 增强
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
的对象进行调用。