Difference between toJSON() and JSON.Stringify()

前端 未结 3 1186
傲寒
傲寒 2020-12-02 13:16

if you need to read or clone all of a model’s data attributes, use its toJSON() method. This method returns a copy of the attributes as an object (not a J

相关标签:
3条回答
  • 2020-12-02 13:25

    From the fine manual:

    toJSON behavior

    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.

    This is why Backbone uses the toJSON method for serialization and given a model instance called m, you can say things like:

    var string = JSON.stringify(m);
    

    and get just the attributes out of m rather than a bunch of noise that your server won't care about.

    That said, the main difference is that toJSON produces a value (a number, boolean, object, ...) that gets converted to a JSON string whereas JSON.stringify always produces a string.

    The default Backbone toJSON is simply this (for models):

    return _.clone(this.attributes);
    

    so m.toJSON() gives you a shallow copy of the model's attributes. If there are arrays or objects as attribute values then you will end unexpected reference sharing. Note that Backbone.Model#clone also suffers from this problem.

    If you want to safely clone a model's data then you could send it through JSON.stringify and then JSON.parse to get a deep copy:

    var data         = JSON.parse(JSON.stringify(model_instance));
    var cloned_model = new M(data);
    

    where model_instance is your instance of the Backbone model M.

    0 讨论(0)
  • 2020-12-02 13:43
    • JSON.stringify() - Any valid JSON representation value can be stringified.

      The JSON.stringify(..) utility will automatically omit undefined, function, and symbol values when it comes across them. If such a value is found in an array, that value is replaced by null (so that the array position information isn't altered). If found as a property of an object, that property will simply be excluded.

      JSON stringification has the special behavior that if an object value has a toJSON() method defined, this method will be called first to get a value to use for serialization.

    • toJSON() - to a valid JSON value suitable for stringification.

      One example, JSON.stringify() an object with circular reference in it, an error will be thrown. toJSON() can fix it as following.

      var o = { };
      var a = {
          b: 32,
          c: o
      };
      
      // circular reference
      o.d = a;
      
      // JSON.stringify( a ); // an error caused by circular reference
      
      // define toJSON method
      a.toJSON = function() {
           return { b: this.b };
      };
      
      JSON.stringify( a ); // "{"b":32}"
      
    0 讨论(0)
  • 2020-12-02 13:46

    I'm also reading Addy Osmani's Developing backbone.js application, and I have the same question. I figured out by trying his example (the todo list) in the console.

    var Todo = Backbone.Model.extend({
        defaults:{
             title:"",
             completed:false
    }
    });
    
    var todo1 = new Todo(); 
    
    
    console.log(todo1.toJSON())
    //The console shows
    //Object {title: "finish your assignment", completed: false}
    
    console.log(JSON.stringify(todo1))
    //The console shows
    //{"title":"finish your assignment","completed":false}
    
    0 讨论(0)
提交回复
热议问题