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

时间:2015-07-02 16:58:34

标签: javascript json node.js stringify

基本上我有类似的东西:

MyClass的

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

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

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;
  });
};

每个类都有自己的stringify实现,所以当我这样做时:

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

我希望调用MyClass.stringify之类的字符串化我的mc对象,但尊重内部对象stringify实现。一旦我们无法控制JSON.stringify方法逻辑,是否有良好的方法可以做到这一点?

谢谢!

1 个答案:

答案 0 :(得分:1)

如果您在JSON.stringify查看MDN,您会看到一个讨论 toJSON 属性的部分

  

如果正在进行字符串化的对象具有名为toJSON的属性,其值为函数,则toJSON()方法自定义JSON字符串化行为:而不是被序列化的对象,调用时toJSON()方法返回的值将是序列

基本上,为 Object 定义一个 toJSON 方法,它创建另一个 Object ,但可以根据需要进行序列化。然后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!"}}'

这也将取代您对当前 stringify 方法的需求。

可悲的是,你无法在JSON.stringify(this)内拨打.toJSON,因为它变成了循环而你得到了RangeError: Maximum call stack size exceeded,但是你无法通过这种方式获得所需的结果,因为它会被序列化第二次,在 JSON 中为您提供 String