Notice that we were able to declare that. However if we were to wrap that JSON in a string, we would get different results:
Uh oh. Let's not list all "89" people that it thinks it found. Instead, let's look at why it thinks that. The problem here is that the string is now simply a string representing object notation, and no longer an actual expression representing an object itself. So when our loop in the code above looks for the initial length of the expression that is evaluated by eval(), it finds the string, and then considers EVERY CHARACTER as it loops through. In each iteration through this very long loop, it fails to find the values we're asking for (it's looking in single characters, not objects that would have the properties we'd expect), and we see many nonsensical lines instead of the two we expect.
" + data + ""; output3.innerHTML += "
" + person.summarize() + ""; /* First let's try to make a clone using JSON.parse - It ignores the functions! */ alert("Let's try using JSON.parse to create a clone from our JSON string, and then explicitly rename the second person 'Bob'..."); var clone = JSON.parse(data); /* We should give him a different name: */ clone.Name = "Bob"; alert(clone.Name+"'s initial properties using 'JSON.parse':\n\n" + getObjectProperties(clone)); alert("Uh oh. It didn't include our summarize() function! Let's try the JSON.clone function instead."); /* JSON.clone works better, because it also factors in the prototype properties (the functions!) */ clone = JSON.clone(data, Person.prototype); /* Let's rename him again: */ clone.Name = "Bob"; alert(clone.Name+"'s properties using 'JSON.clone':\n\n" + getObjectProperties(clone)); alert("Terrific! Now it uses the functions! \ The slightly tweaked JSON.clone function also loops through the prototype \ that you pass along to see what functions it should include with the copy of \ your otherwise static object."); output3.innerHTML += "
" + clone.summarize() + "";
Let's tear this sample apart a little. First of all, we have the specification of a class by declaring a function called Person. Note that instead of specifying the 'summarize()' function directly in the function, I modified it's "prototype" after the fact. There's a very specific reason for that, which I'll discuss below. In any case, each instance of a Person has a Name (a string) and a set of Interests (an array of strings). Each Person can also be summarized, in which case a string is returned giving a brief description of what we know about them.
Once we have a function that describes our Person class, we can start making people. Let's make one, name him "Jonathan", and give him three interests:
If we summarize Jonathan, we'll get the string we expect from the summarize() function in the prototype for that object. Unfortunately, the JSON.parse() function that is built into some browsers (and provided as code in main.js mentioned above in case of browsers that don't natively support it) doesn't factor in the functions that an object might have. I've created a slightly improved JSON.clone(json,prototype) function that let's you not only pass in the JSON string, but also the prototype containing the functions that should be attached to the object once it's cloned, so you get a more complete copy. You can find that function with the other two (which are credited to their source) in the source code (see main.js). Using that function, creating a clone of an instance of an object is as easy as calling the function with the data to parse and the prototype to model it's functionality on: