Anulación de variable JSON global

Tuve que usar json2.js en mi proyecto como navegador (IE8), el objeto JSON no estaba disponible para analizar cadenas en JSON.

Ejecuté json2.js y tengo dudas con la declaración de variables.

Una variable global JSON se declara en json2.js como

var JSON;
if(!JSON){
    JSON={};
}

¿Cuál es el efecto de la declaración? var JSON; en el objeto JSON global. Espero que la declaración anule el objeto JSON global en cualquier navegador (IE8/IE7). Pero para mi sorpresa, no se anula cuando un objeto global está disponible. ¿Solo una definición de variable / iniciación anula una variable global? La amabilidad de aclarar.

preguntado el 02 de mayo de 12 a las 19:05

IE 8 tiene JSON cuando está configurado para modo estándar -

Pero mi página web de intranet (con JSF y Richfaces) siempre se carga en modo IE7. Esa es una historia diferente. -

4 Respuestas

Para cada variable declaración (¿No estás registrado como inicialización!). Sucede lo siguiente (. #10.5):

8. Para cada VariableDeclaration y VariableDeclarationNoIn d en el código, en el orden del texto fuente hacer

  1. Asegúrate de que dn ser la Identificador in d.
  2. Asegúrate de que varYaDeclarado ser el resultado de llamar env de Paso de método concreto HasBinding dn como argumento.
  3. If varYaDeclarado is false, entonces
    1. Llame al env de Paso de método concreto CreateMutableBinding dn y enlaces configurables como los argumentos.
    2. Llame al env de Paso del método concreto SetMutableBinding dn, indefinidoy estricto como los argumentos.

Así que ya ves, siempre que var x se encuentra, se prueba si una variable con nombre x ya existe en el medio ambiente. Si es así, simplemente se ignora, pero si no, entonces la variable se declara e inicializa con undefined.

Dado que el código se ejecuta en un ámbito global, prueba si JSON existe en el ámbito global. Así que si JSON ya existe, var JSON; simplemente se ignora.


Solo algunos pensamientos con respecto a probar/explicar este comportamiento:

No sé en qué punto de la ejecución de JavaScript se crea el objeto global, pero supongo que antes de que se evalúen todos los demás scripts. Eso significa, JSON existe y tiene un valor antes cualquier declaración de variable, algo que solo puede simular si incluye dos scripts (supongo que también pueden estar en línea, se evalúan después de otro).

Tratar:

// script1.js
var foo = 'bar';

// script2.js
var foo;
if(!foo) {
    foo = 'baz';
}
alert(foo);

// include script2.js after script1.js

¿Cuál es el resultado? (tramposos mira aqui).


Siempre que esté en un solo archivo de script, todas las declaraciones de variables se elevan a la parte superior de todos modos. entonces si tienes

var foo = 'bar';
var foo;
if(!foo) {
    foo = 'baz';
}

el script se ejecuta realmente como:

var foo;
var foo;
foo = 'bar';
if(!foo) {
    foo = 'baz';
}

En realidad, no podría probar si el segundo var foo; sobrescribe el primero, ya que en este punto todavía no tiene valor. Así que este no es un buen ejemplo para demostrar el comportamiento citado anteriormente.

contestado el 02 de mayo de 12 a las 19:05

La palabra clave var garantiza que haya una variable en la función adjunta o (como aquí) en la ventana, pero no inicializa una.

De hecho, el orden realmente no impacta.

Mira este código como ejemplo:

a = 3;
var a;
alert(a);

Alerta "3".

Entonces, la declaración var en el código que muestra simplemente garantiza que no habrá errores en la prueba y no elimina el valor existente.

Es bueno tener esto en cuenta porque un error común en javascript es tener más de una declaración de var en una función y sorprenderse con el valor establecido incluso antes de la declaración de var. Ejecuta esto por ejemplo:

if (true) {
    ​a = 3;
}
// lot of code, at a different level
if (true) {
    var a;
    if (433/43==3) a=true;
    if (a) alert('should not happen');
};
​

Sí, la var está adjunta a la función, no al bloque...

contestado el 02 de mayo de 12 a las 19:05

Sin embargo, aquí es un poco diferente. En su ejemplo, la declaración variable es levantado a la cima. Entonces, incluso si lo escribes así, el orden de ejecución real es var a; a = 3; (o tal vez es var a; a = 3; var a; (not hoisted) lo que también tendría sentido y luego encajaría). En este caso, JSON es un símbolo predefinido en el entorno, que ya tiene un valor (supongo) antes de que se evalúe la declaración de la variable. No sé, solo quería señalar la diferencia. - Félix Kling

Puede que no sea una opción para usted, pero también es posible configurar IE8 en modo de compatibilidad para recuperar el objeto JSON nativo:

// in your preinit page event
Response.AddHeader("X-UA-Compatible", "IE=8");

La otra opción sería crear la variable JSON solo si no existe:

var JSON = JSON || {};

contestado el 02 de mayo de 12 a las 19:05

Si está en el ámbito global al ejecutar ese bloque de código, entonces var JSON sobrescribirá el objeto JSON global a indefinido.

Si está en cualquier otro ámbito (como dentro de una función), no habrá ningún efecto.

contestado el 02 de mayo de 12 a las 19:05

Normalmente el guión is ejecutado en ámbito global. Entonces, ¿por qué está allí? - Félix Kling

Lo que quiero decir es: se ejecuta en un ámbito global y no sobrescribir el global JSON objeto si existe. ¿Por qué debería? Eso sería un completo desperdicio. - Félix Kling

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.