使用JSON.stringify()时,json2.js似乎忽略了父对象的成员.例:
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));
Run Code Online (Sandbox Code Playgroud)
输出是:
4
{"someVal":50}
Run Code Online (Sandbox Code Playgroud)
我希望这个输出:
4
{"position":0, "someVal":50}
Run Code Online (Sandbox Code Playgroud)
Tom*_*ana 34
那就是它的方式,JSON.stringify
不保留对象的任何非拥有属性.您可以在这里查看有关其他缺点和可能的解决方法的有趣讨论.
另请注意,作者不仅记录了问题,还编写了一个名为HydrateJS的库,可能对您有所帮助.
这个问题比第一眼看上去要深一点.即使它a
真的会字符串化{"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;
}
Run Code Online (Sandbox Code Playgroud)
写入函数的方式不会改变原始对象.所以使用
console.log(JSON.stringify(flatten(a)));
Run Code Online (Sandbox Code Playgroud)
你会得到你想要的输出,并a
保持不变.
Ces*_*ela 21
另一种选择是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"}"
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为JSON.stringify toJSON
在尝试本机序列化之前在其接收的对象中搜索方法.
检查这个小提琴: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);
}
Run Code Online (Sandbox Code Playgroud)
这是他的答案中包含的代码段@TomasVana 的递归版本,以防在对象树的多个级别存在继承:
var flatten = function(obj) {
if (obj === null) {
return null;
}
if (Array.isArray(obj)) {
var newObj = [];
for (var i = 0; i < obj.length; i++) {
if (typeof obj[i] === 'object') {
newObj.push(flatten(obj[i]));
}
else {
newObj.push(obj[i]);
}
}
return newObj;
}
var result = Object.create(obj);
for(var key in result) {
if (typeof result[key] === 'object') {
result[key] = flatten(result[key]);
}
else {
result[key] = result[key];
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
并将数组保留为数组。以同样的方式调用它:
console.log(JSON.stringify(flatten(visualDataViews)));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
13956 次 |
最近记录: |