2010-07-29 13 views
20

¿Me podría decir la razón de esta estructura de sintaxis específicaPor qué la cita abierta y el soporte para la eval ('(' + jsonString + ')') al analizar cadena JSON

eval('(' + jsonString+ ')') 

Al analizar el texto JSON. Crockford dice "El texto debe estar envuelto en parens para evitar tropezar con una ambigüedad en la sintaxis de JavaScript". here. Qué significa eso?

¿Lo podemos evitar?

+4

Si continúa leyendo la oración después de la que ha citado, desde la página que ha vinculado, verá por qué no debe usar 'eval' para este trabajo * en absoluto * –

+3

Esa razón de eva evaluar es algo de lo que estoy consciente, de todos modos, gracias por señalar. – nepsdotin

Respuesta

24

La ambigüedad de sintaxis a la que se refiere Crockford es que si una llave de apertura no se encuentra en la expresión contexto, se reconocerá como un block, y no como el inicio de un objeto literal.

Por ejemplo:

{"foo": "bar"} // SyntaxError 

le dará un error de sintaxis, porque va a ser interpretado como un bloque, con una cadena literal "foo", y un uso inesperado de la ficha :.

Por otro lado, los paréntesis, formalmente llamados the grouping operator, sólo se puede evaluar expresiones, por lo tanto, no vamos a tener ninguna ambigüedad sintaxis, porque un bloque sólo se puede esperar en un contextocomunicado.

({"foo": "bar"}) 

Editar:@el.pescado hace una pregunta interesante:

Puede explicar por qué eval ('{}') es indefinido?

ECMAScript describe un tipo interno para explicar el comportamiento de los estados, se llama The Completion Specification Type.

valores del tipo de finalización son triples de la forma de (type, value, target), donde type puede ser normal, break, continue, return, o throw.

value puede ser cualquier valor de idioma o empty y target cualquier identificador o empty.

un bloque vacío (la producción Block : {}) devuelve explícitamente la siguiente conclusión:

Return (normal, empty, empty). 

La función eval, después de ejecutar el código, y que sale del contexto de ejecución recién creado, comprueba la finalización resultado del código evaluado , y en el paso 7, podemos ver que se devuelve de forma explícita undefined si el tipo de terminación es normal y el valor de realización es empty:

...

7- Si result.type es normal y su valor de finalización está vacío, devuelve el valor indefinido.

...

+1

Consulte este borrador de publicación de blog nunca publicado, sobre [Tipo de finalización] (http://j.mp/gI9IRv) – CMS

0

un objeto necesita literales para ser envuelto de paréntesis, a ser evaluado apropiadamente en eval contexto y otros contextos:

eval('{}') está definido, por ejemplo. mientras que eval('(' + '{}' + ')') evalúa a Object.

Si ha intentado esto en la consola, por ejemplo: {"foo":"bar"} le arrojaría una etiqueta no válida. Envuélvalo entre paréntesis y se convierte en una expresión válida.

+0

¿podría explicarlo realmente el infractor? –

+1

¿Puedes explicar por qué 'eval ('{}')' no está definido? –

+0

@ el.pescado: pregunta interesante, revise mi [respuesta editada] (http://stackoverflow.com/questions/3360356/why-the-open-quote-and-bracket-for-eval-jsonstring-when-parsing- json/3360404 # 3360404). – CMS

0

@ el.pescado, la cadena después de ejecutado por eval debe haber JavaScript comprensible. es decir, si está asignando la cadena anterior a la variable de la siguiente manera

eval ('var foo1 = {"foo": "bar"}'); foo1.foo volverá barra

así, mi suposición es, ya que no hay declaración como que empieza con "{" en javascript, que está lanzando el error.

+0

A [Bloque] (http://ecma262-5.com/ELS5_HTML.htm#Section_12.1) se considera como una declaración, 'eval ('{}')' no produce ningún error, solo es un bloque vacío. – CMS

+0

'var' parece ser ilegal en una cadena que pasa a' eval() ', ¿su código funcionó en algún navegador anterior (quizás con soporte ES3 solamente)? – CoDEmanX

Cuestiones relacionadas