2012-10-08 24 views
5

Supongamos que tengo el siguiente script, llamado include_strict.js. Después se ejecuta debería haber definido window.global1:"use strict"; + jQuery.getScript() = el script no puede exportar al espacio de nombres global

"use strict"; 

var globalVar = {}; 
alert(typeof window.globalVar); 

Pero si lo incluyo en un bloque de Javascript con

$.getScript("include_strict.js"); 

La alerta dice undefined. ¿Por qué? ¿Que esta pasando aqui?

su información, eso no es lo que ocurre si incluyo el archivo con una etiqueta de script:

<script type="text/javascript" src="include_strict.js"></script> 

Aquí, ver la alerta esperado, object. Y si elimino "use strict";, entonces jQuery.getScript() y <script>; tienen el mismo efecto de mostrar object.

He creado un ejemplo (https://docs.google.com/file/d/0B-XXu97sL1Ckb0x0OHptTmVMY00/edit) para demostrar esto.

Respuesta

11

Utiliza $.getScript() que utiliza eval para ejecutar la secuencia de comandos que no puede modificar el alcance global en el modo estricto:

En segundo lugar, eval de código de modo estricto no introduce nuevas variables en el ámbito circundante. En el código normal eval("var x;") introduce una variable x en la función circundante o el alcance global. Esto significa que, en general, en una función que contiene una llamada para evaluar cada nombre que no hace referencia a un argumento o una variable local debe correlacionarse con una definición particular en tiempo de ejecución (porque esa evaluación podría haber introducido una nueva variable que ocultaría la variable externa) En modo estricto eval crea las variables sólo para el código que está siendo evaluado, por lo eval no puede afectar si un nombre se refiere a una variable externa o alguna variable local:

Fuente: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode

La solución no está utilizando jQuery para cargar el script pero anexando un elemento script al DOM. Tenga en cuenta que ni siquiera puede usar jQuery para agregar el elemento; automáticamente usará $.getScript() para ello.

+0

Me venció por algunos segundos ;-) – Prinzhorn

+0

muy interesante. Me encontré con este tema por primera vez y tiene mucho sentido. Mi problema es que necesito ejecutar varios scripts en orden después de que se carguen, así que necesito saber cuándo se cargó el script antes de agregar el siguiente script. ¿Hay alguna manera de saber cuándo se ha cargado un script si utilizo el método de agregar el script al DOM? ¿funcionaría .load()? – Redtopia

2

jQuery eval uates la secuencia de comandos. "uso estricto"; dentro de eval cambia la semántica del código. ¡Por eso el modo estricto puede ser peligroso! Porque en los navegadores que no lo admiten, su código hace otra cosa.

En segundo lugar, la evaluación del código de modo estricto no introduce nuevas variables en el ámbito circundante. En el código normal eval ("var x;") introduce una variable x en la función circundante o en el alcance global. Esto significa que, en general, en una función que contiene una llamada para evaluar cada nombre que no hace referencia a un argumento o una variable local debe correlacionarse con una definición particular en tiempo de ejecución (porque esa evaluación podría haber introducido una nueva variable que ocultaría la variable externa) En modo estricto eval crea variables solo para el código que se evalúa, por lo que eval no puede afectar si un nombre se refiere a una variable externa o alguna variable local.

https://developer.mozilla.org/en/JavaScript/Strict_mode

La solución es utilizar window.foo = "bar;" en lugar de var foo = "bar";. Y debe poner su código dentro de un IIFE para hacer "uso estricto"; más predecible

(function(window) { 
    "use strict"; 

    window.globalVar = {}; 
    alert(typeof window.globalVar); 
}(window)); 
+0

No es exactamente lo que necesitaba, pero me hizo 'clic' - ¡muchas gracias! :) –

0

proceso de eliminación de la respuesta del modo terminante antes de ejecutar:

$.ajax({ 
    url: scriptUrl, 
    dataType: "script", 
    dataFilter: function (data, type) { 
     return data.replace("\'use strict\';", ""); 
    } 
}); 
Cuestiones relacionadas