Reputation: 1
My objective is to translate an object into text form that can be stored using, say, localStorage, and subsequently retrieved and converted back to its original object form using eval(). I have written a function called uneval() to do the conversion to text as follows:
function uneval(obj){
// Convert object to a string that can be evaluated with eval() to its original
if(obj===null)return 'null';
if(typeof obj === 'number' || typeof obj === 'boolean')return ''+obj;
if(typeof obj === 'string')return '"'+obj+'"';
if(Object.prototype.toString.call(obj) === '[object Array]')
{ var str = '[', i=0, l=obj.length;
for(i;i<l;i++)str+= (i==0?'':',') + uneval(obj[i]);
return str+']';
}
if(typeof obj === 'object')
{ var str='({', i;
for (i in obj)str+= (2==str.length?'':',') + i + ':' + uneval(obj[i]);
return str+='})';
}
if(typeof obj === 'function')return '(' + obj.toString() + ')';
return '';}
[Edit 1: An object in {} needs parenthese around to be successfully converted using eval()]
[Edit 2: Function code amended to place parentheses around the function code string]
[Edit 3: Changed to a named function for recursion avoiding arguments.callee]
[Edit 4: Handle null]
Note that this function retains nested structure. It works fine (at least in Google Chrome and MS IE8) except when the object, or an item of the object, is a function. I have found a workaround by making an assignment of the function in string form to an unlikely variable, as "_=". That does the job. Without that, I get a syntax error from eval(). Could anyone explain why that is the case, please?
By the way, I can avoid the small chance of a conflict using _ as a variable by calling eval() within a cover function in which _ is localised.
Upvotes: 0
Views: 141
Reputation: 185913
In this code:
var func = eval('function () {}');
eval
parses the string as a function declaration, not a function expression, and since function declarations cannot be anonymous, a syntax error is thrown. In order to ensure that your string is parsed as a function expression, instead of a declaration, just add parens at the beginning, and end of the string. These parents will be parsed as the grouping operator. The contents of the grouping operator are then parsed as an expression; in this case, a function expression.
var func = eval('(function () {})'); // doesn't throw
So, in your uneval
function, do this:
if ( typeof obj === 'function' ) return '(' + obj.toString() + ')';
Upvotes: 1