2013-02-15 1 views
0

Mon objectif est de traduire un objet sous forme de texte qui peut être stocké en utilisant, par exemple, localStorage, puis récupéré et converti à sa forme d'objet d'origine en utilisant eval(). J'ai écrit une fonction appelée uneval() pour effectuer la conversion en texte comme suit:Conversion d'objets en texte pouvant être reproduit par eval(); anomolies avec l'objet fonction

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: Un objet {} doit Parenthese autour d'être converti avec succès en utilisant eval()]

[Edit 2: code de fonction modifié pour placer des parenthèses autour de la chaîne de codes de fonction]

[Edit 3: Modification de la fonction appelée pour la récursion en évitant arguments.callee]

[Modifier 4: Poignée null]

Notez que cette fonction conserve la structure imbriquée. Cela fonctionne bien (au moins dans Google Chrome et MS IE8) sauf lorsque l'objet, ou un objet de l'objet, est une fonction. J'ai trouvé une solution de contournement en faisant une affectation de la fonction sous forme de chaîne à une variable improbable, comme "_ =". Cela fait le travail. Sans cela, j'obtiens une erreur de syntaxe de eval(). Quelqu'un pourrait-il expliquer pourquoi c'est le cas, s'il vous plaît? Par ailleurs, je peux éviter la petite chance d'un conflit en utilisant _ comme une variable en appelant eval() dans une fonction de couverture dans laquelle _ est localisée.

+0

Side note: 'arguments.callee' jette dans la langue stricte, vous devriez donc * pas * l'utiliser plus. –

+1

De plus 'typeof null' renvoie' 'object''. Vous devriez tenir compte de cela. –

+0

De même, votre code ne l'indique pas clairement, mais 'unval' devrait être déclaré à l'avance (par exemple' var uneval; '). Sinon, il devient une propriété globale implicite qui est aussi une violation du langage strict. –

Répondre

1

Dans ce code:

var func = eval('function() {}'); 

eval parse la chaîne en fonction déclaration, pas une fonction expression, et puisque les déclarations de fonction ne peuvent pas être anonymes, une erreur de syntaxe est générée. Afin de vous assurer que votre chaîne est analysée en tant qu'expression de fonction, au lieu d'une déclaration, ajoutez simplement des parens au début et à la fin de la chaîne. Ces parents seront analysés comme grouping operator. Le contenu de l'opérateur de regroupement est ensuite analysé en tant qu'expression; dans ce cas, une expression de fonction.

var func = eval('(function() {})'); // doesn't throw 

Ainsi, dans votre fonction uneval, faites ceci:

if (typeof obj === 'function') return '(' + obj.toString() + ')'; 
+0

vidas: Un grand merci pour votre temps et explication lucide. – crosseyed

+0

@crosseyed J'ai amélioré mes connaissances sur eval, donc c'est gagnant-gagnant ':-)' –

Questions connexes