34 votes

Pourquoi JavaScript eval besoin des parenthèses pour eval données JSON?

J'ai appris (à la dure) que j'ai besoin d'ajouter des parenthèses autour des données JSON, comme ceci:

stuff = eval('(' + data_from_the_wire + ')');
// where data_from_the_wire was, for example {"text": "hello"}

(Dans Firefox 3, au moins).

Quelle est la raison derrière tout cela? Je déteste écrire du code sans comprendre ce qui est derrière le capot.

63voto

karim79 Points 178055

eval accepte une séquence d'instructions Javascript. Le parser Javascript interprète le ‘{' token, se produisant dans un énoncé comme le début d'un bloc et non le début d'un objet littéral.

Lorsque vous placez votre littérale dans les parenthèses comme ceci: ({ data_from_the_wire }) vous passez le parser Javascript dans l'expression mode d'analyse. Le jeton ‘{' à l'intérieur d'une expression signifie le début d'un objet littéral de la déclaration et non d'un bloc, et donc Javascript accepte comme un objet littéral.

39voto

Kazar Points 16014

Mettre des parenthèses autour de data_from_the_wire est équivalent à

stuff = eval('return ' + data_from_the_wire + ';');

Si vous étiez à eval sans les parenthèses, puis le code devrait être évaluée, et si vous aviez un nom de fonctions à l'intérieur d'elle ceux qui seraient définis, mais n'est pas retourné.

Prenez comme exemple la possibilité d'appeler une fonction comme il le han été créé:

(function() { alert('whoot'); })()

Appelle la fonction qui vient d'être défini. La suite, cependant, ne fonctionne pas:

function() { alert('whoot'); }()

Nous voyons donc que les parenthèses efficacement tournez ensuite le code dans une expression qui renvoie, plutôt que de simplement l'exécution de code.

11voto

Garry Shutler Points 20898

Je ne suis pas sûr de la raison, mais je parser JSON en utilisant la classe JSON à partir de json.org. Il est beaucoup plus sûr que d'utiliser eval.

9voto

Salman A Points 60620

En JavaScript, les accolades sont utilisées pour créer des blocs d'instructions:

{
var foo = "bar";
var blah = "baz";
doSomething();
}

Les lignes ci-dessus peut être mis à l'intérieur d'une chaîne et d' evalzanne, sise sans problème. Maintenant, considérez ceci:

{
"foo": "bar",
"blah": "baz"
}

Les accolades cause le moteur JavaScript pense que c'est un groupe d'expression, d'où l'erreur de syntaxe autour de l' : de caractère. Citation de MDN...JavaScript Guide...Littéraux d'Objet:

Vous ne devriez pas utiliser un objet littéral au début d'un énoncé. Cela conduira à une erreur ou ne pas se comporter comme prévu, parce que le { sera interprété comme le début d'un bloc.

La solution d'emballage de l'objet littéral à l'intérieur d' () travaux en racontant le moteur pour traiter son contenu comme une expression, non pas comme un bloc de déclaration. Donc cela ne fonctionne pas:

({
var foo = "bar";
var blah = "baz";
doSomething(evil);
})
// parse error

Mais ce n':

({
"foo": "bar",
"blah": "baz"
})
// returns object

2voto

drdaeman Points 3312

Cela se produit parce que sans tour accolades JavaScript tente d'interpréter {"text": ... comme une étiquette et échoue. Essayez-la dans la console et vous obtiendrez "étiquette non valide" erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X