Pregunta

He aprendido (la forma más dura) que tengo que añadir entre paréntesis los datos JSON, como esto:

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

(En Firefox 3, al menos).

¿Cuál es la razón detrás de esto? Odio escribir código sin entender Cómo detrás de la capucha.

¿Fue útil?

Solución

Poner los paréntesis alrededor de data_from_the_wire es efectivamente equivalente a

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

Si se va a eval sin los paréntesis, a continuación, el código sería evaluado, y si tenían ninguna funciones con nombre dentro de ella los que serían definidos, pero no regresó.

Tome como ejemplo la posibilidad de llamar a una función tal y como de han sido creado:

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

llamará a la función que acaba de ser definido. A continuación, sin embargo, no funciona:

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

Así vemos que los paréntesis se convierten efectivamente a continuación código en una expresión que devuelve, en lugar de sólo la ejecución de código.

Otros consejos

eval acepta una secuencia de sentencias de JavaScript. El analizador Javascript interpreta la ‘{’ ficha, que ocurren dentro de una sentencia como el inicio de un bloque y no el comienzo de un objeto literal.

Cuando se delimita su literal al paréntesis como éste: ({ data_from_the_wire }) está cambiando el analizador de JavaScript en el modo de expresión de análisis. El token ‘{’ dentro de una expresión significa el inicio de una declaración literal objeto y no un bloque, y por lo tanto Javascript acepta como un objeto literal.

No estoy seguro de la razón pero yo analizo JSON mediante el uso de la clase JSON desde json.org . Es mucho más seguro que usar eval.

En JavaScript, entre llaves se utilizan para crear las instrucciones de bloque:

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

Las líneas anteriores se pueden poner dentro de una cadena y evaluated sin problema. Ahora considere esto:

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

Las llaves hacen que el motor de JavaScript a pensar que es una expresión de grupo, de ahí el error de sintaxis en torno al personaje :. Presupuesto de MDN ... Guía de JavaScript ... literales de objetos :

  

No debe utilizar un objeto literal al comienzo de un comunicado.   Esto dará lugar a un error o no se comporta como se esperaba, debido a que el {   será interpretado como el comienzo de un bloque.

La solución de envolver el objeto literal dentro () funciona contando el motor para el tratamiento de su contenido como una expresión, no como una sentencia de bloque. Así que esto no funciona:

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

Sin embargo, esto hace:

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

Esto sucede porque sin llaves redondas JavaScript trata de interpretar como {"text": ... una etiqueta y falla. Probarlo en la consola y obtendrá "etiqueta válido".

Depende del valor de data_from_the_wire, en realidad. En la mayoría de los casos, su sintaxis es aceptable, pero una línea que comienza con { se analiza como una etiqueta, y los suyos no es válido. Si usted se rodea con paréntesis, impide que el analizador de malinterpretar su expresión.

Sólo un problema de análisis, de verdad. Con cadenas, números o funciones, que no tendría ese problema.

Una solución es siempre las instrucciones de evaluación y NO expresiones. Se puede escribir

eval('var stuff = {"text": "hello"}');

No sé, y estoy realmente interesado en la respuesta a esto, pero mi conjetura es que sin los paréntesis, los datos de data_from_the_wire serían interpretadas como un cierre. Tal vez la evaluación vigor paréntesis, por lo que el arreglo asociativo es 'devuelta'.

Este es el tipo de adivinanzas que conduce a downvotes aunque =).

Editar

Douglas Crockford menciona una ambigüedad en su sintaxis JSON sitio, pero que en realidad no ayudan yo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top