json2.js在使用JSON.stringify()时似乎忽略了父对象的成员。示例:
require('./json2.js');
function WorldObject(type) {
this.position = 4;
}
function Actor(val) {
this.someVal = 50;
}
Actor.prototype = new WorldObject();
var a = new Actor(2);
console.log(a.position);
console.log(JSON.stringify(a));输出为:
4
{"someVal":50}我希望得到以下输出:
4
{"position":0, "someVal":50}发布于 2012-01-09 01:11:38
事实就是这样,JSON.stringify不会保留该对象的任何不属于它的属性。您可以查看有关here的其他缺点和可能的变通方法的有趣讨论。
还要注意,作者不仅记录了这些问题,而且还编写了一个名为HydrateJS的库,它可能会对您有所帮助。
这个问题比乍一看要深一点。即使a真的将stringify转换为{"position":0, "someVal":50},稍后解析它也会创建一个具有所需属性的对象,但它既不是Actor的实例,也不是指向WorldObject的原型链接(毕竟,解析方法没有这些信息,所以它不可能以这种方式恢复它)。
为了保留原型链,需要一些聪明的技巧(就像HydrateJS中使用的那些)。如果这不是你的目标,也许你只需要在串化对象之前“扁平化”它。要做到这一点,你可以迭代对象的所有属性,不管它们是否是拥有的,并重新分配它们(这将确保它们在对象本身上定义,而不只是从原型继承)。
function flatten(obj) {
var result = Object.create(obj);
for(var key in result) {
result[key] = result[key];
}
return result;
}函数的编写方式不会改变原始对象。所以使用
console.log(JSON.stringify(flatten(a)));您将获得所需的输出,而a将保持不变。
发布于 2012-12-29 10:46:32
另一种选择是在要序列化的对象原型中定义一个toJSON方法:
function Test(){}
Test.prototype = {
someProperty: "some value",
toJSON: function() {
var tmp = {};
for(var key in this) {
if(typeof this[key] !== 'function')
tmp[key] = this[key];
}
return tmp;
}
};
var t = new Test;
JSON.stringify(t); // returns "{"someProperty" : "some value"}"这是因为在尝试本机序列化之前,JSON.stringify会在它接收到的对象中搜索toJSON方法。
发布于 2012-01-09 01:30:49
检查这个小提琴:http://jsfiddle.net/AEGYG/
您可以使用此函数对对象进行扁平字符串化:
function flatStringify(x) {
for(var i in x) {
if(!x.hasOwnProperty(i)) {
// weird as it might seem, this actually does the trick! - adds parent property to self
x[i] = x[i];
}
}
return JSON.stringify(x);
}https://stackoverflow.com/questions/8779249
复制相似问题