Javascript toSource() in IE6/7

Mozilla based browsers have a pretty nifty instance method “toSource()”. It simply outputs a string literal representation of any Javascript object, which is at heart, *anything* in the Javascript interpreter.

The main reason I use this method is to do a quick & dirty deep copy of Javascript objects and arrays. When paired with the “eval()” function, you can be 100% sure that the new array or object you just created is its own instance and doesn’t have reference pointers to existent objects or arrays.

My main use-case is using an object as hashmap or associative array, but needing to copy it regardless of whether one of its member attributes is another object or array (which would preserve the pointer). Performing a toSource() and eval() allow you to do just this.

var burdensomeBabyNames = [ ... ]; // imagine a deep array of strings, other arrays, objects, etc.
// now we have a deep copy, quick and easy|dirty
var burdensomeBabyNamesCopy = eval(burdensomeBabyNames.toSource());

For example, say you have an array of names in memory: “Oedipus”, “Ophelia”, “Freya”, “Loki”, “Lachesis”, “Atropos”, and “Morta”.

If that array was instantiated in memory as “burdensomeBabyNames”, the string literal representation would look something like:

var burdensomeBabyNames = [
  'Oedipus', 'Ophelia', 'Freya', 'Loki',
  'Lachesis', 'Atropos', 'Morta'
];

In a Mozilla based browser, one could call “toSource()” return an useful textual representation of the string literal. I.e., calling:

var xNames = burdensomeBabyNames.toSource();

The var xNames would now contain the string:

['Oedipus','Ophelia','Freya','Loki','Lachesis','Atropos','Morta']

Great, huh? That’s really useful if you never have to consider the Internet Explorer crowd, but since IE still owns a ridiculously high percentage of the browser usage pie, folks who use this functionality need a work-around.

Anyone who’s worked with asynchronous calls vis-a-vis JSON (Javascript Object Notation, see http://www.json.org) will see that the toSource() call is just a rough draft of the much deeper JSON.encode().

The same example as above could be rewritten to use JSON encode and decode:

var burdensomeBabyNames = [ ... ]; // imagine a deep array of strings, other arrays, objects, etc.

// serialize or "toSource()" the array
var burdensomeBabyNamesJSON = JSON.encode(burdensomeBabyNames);

// now we have a deep copy, quick and easy|dirty
var burdensomeBabyNamesCopy = JSON.decode(burdensomeBabyNamesJSON);

One could just include the minified version of JSON.js from the above link and call it good. If you happen to be working within a framework like YUI (Yahoo UI, see http://developer.yahoo.com/yui) or ExtJs (see http://www.extjs.com), the encode/decode functionality is already folded into the core library.

Advertisements