2010-09-29 6 views
5

Pourquoi le code suivant doit-il ajouter ( et ) pour eval?Pourquoi avons-nous besoin d'ajouter des parenthèses pour évaluer JSON?

var strJson = eval("(" + $("#status").val().replace(";","") + ")"); 

PS: $("#status").val() est de retour quelque chose comme {"10000048":"1","25000175":"2","25000268":"3"};

+0

Pourquoi utilisez-vous 'eval' en premier lieu? Il suffit de coller avec:.. 'var strJson = $ ("# status") val() remplacer (";", "");' –

Répondre

3

eval prend une instruction JavaScript ou une expression, mais {...} serait valide comme une instruction ou une expression, et la grammaire de JavaScript préfère une déclaration.

Comme expression:

{"10000048":"1","25000175":"2","25000268":"3"} 

est un objet avec des propriétés (ce que vous voulez).

Comme une déclaration, il est un bloc:

{      // begin Block 
    "10000048":   // LabelledStatement (but the quotes are invalid) 
     "1",   // Expression, calculate string "1" then discard it, then 
      "25000175": // you can't put a label inside an expression 

qui donne une erreur.

(étiquettes JavaScript peuvent être utilisés pour marquer une déclaration particulière pour une utilisation avec break/continue. Ils sont un peu inutile et presque jamais utilisé.)

Ainsi en ajoutant les parenthèses vous résoudre l'ambiguïté. Seule une expression peut commencer par (, donc le contenu est analysé dans un contexte d'expression, donnant un objet littéral, pas un contexte d'instruction. Incidemment, ce n'est pas assez assez pour interpréter correctement toutes les valeurs JSON possibles. En raison d'un oubli dans la conception de JSON, les caractères U + 2028 et U + 2029, deux caractères de fin de ligne Unicode obscurs, sont valides pour être mis en échappement dans un littéral de chaîne JSON, mais pas dans un littéral de chaîne JavaScript.Si vous voulez être sûr, vous pouvez leur échapper, par exemple:

function parseJSON(s) { 
    if ('JSON' in window) return JSON.parse(s); 
    return eval('('+s.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029')+')'); 
} 
4

Cela dépend de la valeur de cet élément est (un inconnu), l'enveloppant dans () est la voie sûre pour tenir compte éventuellement de pas d'entrée être là.

Edit: Maintenant que vous avez éclairci ce de JSON, ce n'est pas valide:

eval('{"10000048":"1","25000175":"2","25000268":"3"}'); 

Mais cela se traduira par un objet valide de retour:

eval('({"10000048":"1","25000175":"2","25000268":"3"})'); 
//effectively: 
eval('return {"10000048":"1","25000175":"2","25000268":"3"};'); 

image dans un JavaScript fichier:

<script type="text/javascript"> 
    {"10000048":"1","25000175":"2","25000268":"3"} 
</script> 

Cela va à l'échec, il est juste un objet déclaré en ligne mais pas la syntaxe correcte ... la La même raison qu'un serveur a pour soutenir JSONP pour que cela fonctionne.


Un peu tangent à la question, mais puisque vous incluez jQuery, vous pourriez aussi bien utiliser $.parseJSON() (qui utilisera la JSON.parse() native si elle est disponible) pour cela:

var strJson = $.parseJSON($("#status").val().replace(";","")); 
+0

Salut val() retourné est quelque chose comme { "10000048": "1 », "25000175": "2", "25000268": "3"}; – Ricky

+0

pourquoi la première instruction est invalide – Ricky

+0

@Ricky - Ce n'est pas une syntaxe valide pour la même raison que ce n'est pas directement dans le script, puisque l'analyseur ne la considère pas comme une expression alors qu'ajouter '()' est une déclaration de retour (car il passe à une expression, la reconnaissance '' {comme un début d'objet, obtenir/retour l'objet que vous aimez). –

Questions connexes