简体   繁体   English

字符串化JSON内部对象的最佳实践

[英]Best practices for stringifying JSON inner objects

Basically I have something like this: 基本上我有这样的事情:

MyClass 我的课

var MyClass = function() {
  this.num = 123;
  this.obj = new MyInnerClass();
};

MyClass.prototype.stringify = function() {
  return JSON.stringify(this);
};

MyInnerClass MyInnerClass

var MyInnerClass = function() {
  this.foo = 456;
  this.bar = 'bonjour!';
};

MyInnerClass.prototype.stringify = function() {
  return JSON.stringify(this, function(k, v) {
    // ignores 'foo' attribute
    return k !== 'foo' ? v : undefined;
  });
};

Each class has its own stringify implementation, so when I do: 每个类都有其自己的stringify实现,因此当我这样做时:

var mc = new MyClass();
mc.stringify();

I would like something like calling MyClass.stringify should stringify my mc object, but respecting inner objects stringify implementations. 我希望像调用MyClass.stringify类的东西可以对我的mc对象进行字符串化,但是要尊重内部对象对stringify实现的尊重。 Once we don't have control over the JSON.stringify method logic, is there a good way to do that? 一旦我们无法控制JSON.stringify方法逻辑,是否有一个很好的方法来做到这一点?

Thank you! 谢谢!

If you look on MDN at JSON.stringify , you'll see a section that talks about a toJSON property 如果您在JSON.stringify上查看MDN,则会看到有关toJSON属性的部分。

If an object being stringified has a property named toJSON whose value is a function, then the toJSON() method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON() method when called will be serialized. 如果要被字符串化的对象具有名为toJSON的属性,其值是一个函数,则toJSON()方法将自定义JSON字符串化行为:代替被序列化的对象,由toJSON()方法返回的值将被序列化,而不是被序列化的对象。

Basically, define a toJSON method for your Object which creates another Object , but one that can be serialised as you desire. 基本上,为您的Object定义一个toJSON方法,该方法创建另一个Object ,但是可以根据需要将其序列化。 Then JSON.stringify will serialise the return of your toJSON function instead, ie 然后JSON.stringify将序列化您的toJSON函数的返回值,即

var MyClass = function() {
  this.num = 123;
  this.obj = new MyInnerClass();
};

var MyInnerClass = function() {
  this.foo = 456;
  this.bar = 'bonjour!';
};

MyInnerClass.prototype.toJSON = function () {
    // shallow clone `this`, except .foo
    var o = Object.create(null), k, blacklist = ['foo'];
    for (k in this) // loop over enumerable properties
        if (Object.prototype.hasOwnProperty.call(this, k)) // ignore inherited properties
            if (blacklist.indexOf(k) === -1) // ignore blacklisted properties
                o[k] = this[k]; // add to our clone
    return o;
};

JSON.stringify(new MyClass()); // '{"num":123,"obj":{"bar":"bonjour!"}}'

This will also replace your need for the current stringify method. 这也将取代您对当前stringify方法的需求。


Sadly you can't call JSON.stringify(this) inside .toJSON because it becomes circular and you get RangeError: Maximum call stack size exceeded , but you'd not get the desired result this way anyway as it would be serialised a second time, giving you a String in your JSON . 遗憾的是,您无法在.toJSON调用JSON.stringify(this) ,因为它变成了循环并且会出现RangeError: Maximum call stack size exceeded ,但是无论如何您都无法以这种方式获得所需的结果,因为它将第二次序列化,在JSON中给您一个String

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM