2011-01-12 20 views
29

¿Es posible usar el comando eval para ejecutar algo con un alcance global? Por ejemplo, esto causará un error:¿Eva de Javascript en alcance global?

<script> 
function execute(x){ 
eval(x); 
} 

function start(){ 
    execute("var ary = new Array()"); 
    execute("ary.push('test');"); // This will cause exception: ary is not defined 
} 

</script> 
<html><body onLoad="start()"></body></html> 

Sé que el 'con' la palabra clave será establecer un ámbito específico, pero no es una palabra clave para el alcance global? ¿O es posible definir un ámbito personalizado que permita que esto funcione?

<script> 

var scope = {}; 
function execute(x){ 
    with(scope){ 
    eval(x); 
    } 
} 

function start(){ 
    execute("var ary = new Array()"); 
    execute("ary.push('test');"); // This will cause exception: ary is not defined 
} 

</script> 
<html><body onLoad="start()"></body></html> 

En esencia, lo que estoy tratando de hacer es tener un Funciton ejecutar mundial ...

Respuesta

1

Yo sé que habrá muchos comentarios que vienen con eval es malo y estoy de acuerdo con eso. Sin embargo, para responder a su pregunta, cambiar su método de inicio de la siguiente manera:

function start(){ 
    execute("ary = new Array()"); 
    execute("ary.push('test');"); // This will cause exception: ary is not defined 
} 
32
(function(){ 
    eval.apply(this, arguments); 
}(a,b,c)) 

Este invocarán eval con el objeto global, window en los navegadores, como el argumento this pasar ningún argumento que ha pasado a la función anónima

eval.call(window, x, y, z) o eval.apply(window, arguments) también es válido si está seguro window es el objeto global. Sin embargo, esto no siempre es cierto. Por ejemplo, el objeto global en una secuencia de comandos Node.js es process si no recuerdo mal.

+2

'eval.call (windwow, x); 'funcionó para mí, implementación entre navegadores. la razón es que el alcance global siempre debe ser el objeto 'ventana' y las funciones definidas posteriormente pertenecen a este objeto, como en' JSON.stringify', por ejemplo, no es más que 'ventana ['JSON'] ['stringify']' y evento 'ventana ['ventana'] ['ventana'] ['ventana'] ['ventana'] ['JSON'] ['stringify']'; ambos seguirán funcionando. –

+0

¡Esto realmente ayuda! Tenía una "Fecha" establecida localmente por la función que me llamaba y quería la versión global del objeto Date que es window.Date. –

+2

-1. Lee http://perfectionkills.com/global-eval-what-are-the-options/ sobre lo que realmente sucede. – Bergi

5

Debería poder usar eval() en alcance global llamándolo indirectamente. Sin embargo, no todos los navegadores están haciendo esto actualmente.

Further Reading.

2

Para ejecutar JavaScript en el ámbito global puede llamarlo indirectamente usando setTimeout() o si está utilizando jQuery, eche un vistazo a $.globalEval().

Cambiar su método execute a la siguiente le permitirá seguir utilizando el 'var' palabra clave:

function execute(x) { 
    setTimeout("eval(" + x + ")", 0); 
    // Or: $.globalEval(x); 
} 


function start() { 
    try 
    { 
     execute("var ary = new Array()"); 
     execute("ary.push('test');"); 
    } 
    catch (e) 
    { 
     alert(e); 
    } 
} 


start(); 
+0

Deberá citar correctamente lo que esté en x (y haya omitido un '+' después de la x) – Michael

+0

gracias, actualizado –

+0

'$ .globalEval (x);' funcionó muy bien. Más información encontrada en http://stackoverflow.com/questions/7921851/jquery-globaleval-function –

5

Uso (1, eval)('...').

$ node 
> fooMaker = function() { (1, eval)('foo = "bar"'); }; 
[Function] 
> typeof foo 
'undefined' 
> fooMaker() 
undefined 
> typeof foo 
'string' 
> foo 
'bar' 
+2

No estoy seguro de qué tipo de magia negra es esta, pero funciona asombrosamente bien.Me encantaría entender qué diablos está pasando aquí, ¿podrías explicarlo? :) –

0

Usar eval.apply(null, ["code"]);.

eval.apply(this, ["code"]); no funciona en Microsoft Script Host (cscript.exe).

Cuestiones relacionadas