Difference between toJSON() and JSON.Stringify()
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.
From the fine manual:
toJSON behavior
If an object being stringified has a property named
toJSON
whose value is a function, then thetoJSON
method customizes JSON stringification behavior: instead of the object being serialized, the value returned by thetoJSON
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
.
-
JSON.stringify()
- Any valid JSON representation value can be stringified.The
JSON.stringify(..)
utility will automatically omitundefined
,function
, andsymbol
values when it comes across them. If such a value is found in anarray
, that value is replaced bynull
(so that the array position information isn't altered). If found as a property of anobject
, that property will simply be excluded.JSON stringification has the special behavior that if an
object
value has atoJSON()
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()
anobject
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}"
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}