[英]Strange behaviour in JSON.stringify with replacer function
Consider this: 考虑一下:
var object = {date: new Date()};
JSON.stringify(object, function(key, value) {
console.log('---');
console.log('key:', key);
console.log('value:', value);
console.log('value instanceof Date:', value instanceof Date);
return value;
});
As documentation says: 如文档所述 :
The replacer parameter can be either a function or an array.
replacer参数可以是函数或数组。 As a function, it takes two parameters, the key and the value being stringified.
作为一个函数,它需要两个参数,即键和值被字符串化。 The object in which the key was found is provided as the replacer's this parameter.
在其中找到密钥的对象作为替换者的this参数提供。 Initially it gets called with an empty key representing the object being stringified, and it then gets called for each property on the object or array being stringified.
最初,它使用表示要被字符串化的对象的空键调用,然后针对要被字符串化的对象或数组的每个属性调用它。
...
...
If you return any other object, the object is recursively stringified into the JSON string, calling the replacer function on each property, unless the object is a function, in which case nothing is added to the JSON string.
如果返回任何其他对象,则将该对象递归地字符串化为JSON字符串,并在每个属性上调用replacer函数,除非该对象是一个函数,在这种情况下,不会将任何内容添加到JSON字符串。
But if you run the code, you will get this: 但是,如果您运行代码,则会得到以下信息:
---
key:
value: { date: Fri Jan 10 2014 02:25:00 GMT+0100 (CET) }
value instanceof Date: false
---
key: date
value: 2014-01-10T01:25:00.262Z
value instanceof Date: false
It means, that the date property was stringified before replacer function has been called. 这意味着,在调用replacer函数之前,已对date属性进行了字符串化。 Is it a normal behaviour or am I missing something?
这是正常行为还是我错过了一些东西? How can I affect format of
Date
stringification without overriding it's default toJSON
method? 如何在不覆盖默认的
toJSON
方法的情况下影响Date
字符串化的格式?
Thanks! 谢谢!
Based on responses and next research, documentation seems to be unclear at this point and toJSON
is beeing called before the replacer function. 根据响应和下一步研究,目前文档尚不清楚,并且在替换函数之前先调用
toJSON
。 Based on Pills's response, this snippet should do the job: 根据Pills的回复,此代码段应完成以下工作:
var object = {date: new Date };
JSON.stringify(object, function(key, value) {
if (typeof(value) === 'object') {
for (var k in value) {
if (value[k] instanceof Date) {
value[k] = value[k].getTime();
}
}
}
return value;
});
Xotic750's solution is much better than previous one. Xotic750的解决方案比以前的解决方案好得多。
Perhaps you could do your formatting before passing the object to JSON
, but otherwise here is a possibility: 也许您可以在将对象传递给
JSON
之前进行格式化,否则可能会出现这种情况:
JSON
uses an objects toJSON
method before calling the replacer. JSON
在调用toJSON
之前使用对象toJSON
方法。
So, before calling stringify
store the toJSON
method and then restore it afterwards. 因此,在调用
stringify
之前,存储toJSON
方法,然后再将其还原。
var object = {
date: new Date()
},
storeToJSON = Date.prototype.toJSON;
delete Date.prototype.toJSON;
JSON.stringify(object, function (key, value) {
console.log('---');
console.log('key:', key);
console.log('value:', value);
console.log('value instanceof Date:', value instanceof Date);
return value;
});
Date.prototype.toJSON = storeToJSON;
Its quiet old but just to complete it. 它很安静,但只是为了完成它。
According to this Q/A and the MDN JSON.stringify article , the replacer is called with instance of the object in which the key was found so no need to change prototype or do another tricks: 根据此Q / A和MDN JSON.stringify文章 ,将使用在其中找到了密钥的对象的实例调用替换程序,因此无需更改原型或进行其他操作:
function log(what) { what = what || ""; document.getElementById("out").innerText += what + "\\n"; } function replacer(key, value) { console.log(this); log("Key: '" + key + "' = '" + value + "'"); log("this = " + this); log("this[key] = " + this[key]); log("this[key] instanceof Date = " + (this[key] instanceof Date)); log("this instanceof Date = " + (this[key] instanceof Date)); if (this[key] instanceof Date) { return "This was a date: " + this[key].getTime(); } return value; } var obj = { d: new Date() }; var result; result = JSON.stringify(new Date(), replacer); log(); log(result); log(); result = JSON.stringify(obj, replacer); log(); log(result);
<pre id="out"></pre>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.