Difference between toJSON() and JSON.Stringify()

JavascriptJsonbackbone.js

Javascript Problem Overview


> 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 JSON string despite its name). (When JSON.stringify() is > passed an object with a toJSON() method, it stringifies the return > value of toJSON() instead of the original object. The examples in the > previous section took advantage of this feature when they called > JSON.stringify() to log model instances.)

http://addyosmani.github.io/backbone-fundamentals/#backbone-basics

Can anyone tell me the difference between both these ways of representing an object in JSON notation. I am just confused whether these to achieve the same or there is a difference.

Javascript Solutions


Solution 1 - Javascript

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.

Solution 2 - Javascript

  • 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}"
    

Solution 3 - Javascript

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}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShaneView Question on Stackoverflow
Solution 1 - Javascriptmu is too shortView Answer on Stackoverflow
Solution 2 - JavascriptzangwView Answer on Stackoverflow
Solution 3 - JavascriptLijie ZhouView Answer on Stackoverflow