2016-09-17 38 views
6

在JS中使用eval時,我遇到了奇怪的行爲。Javascript可變捕獲

var f = function() { 
    var x = 10; 

    return function() { 
     eval('console.log(x);'); 
     window['eval']('console.log(x);'); 
    } 
}; 

f()(); 

OUTPUT:

10 
undefined:1 
console.log(x); 
      ^
ReferenceError: x is not defined 

爲什麼使用eval明確地捕捉xglobal['eval']不? 即使global['eval']未拍到x,爲什麼在eval之後無法看到,其中已經拍下了x

+5

更好的問題是爲什麼要使用eval? eval做了不可思議的事情。最好不要管它。 –

+1

有時候爲了遠程測試,我需要快速加載並運行我的本地代碼。不適用於生產代碼:) –

+0

http://stackoverflow.com/a/17281213/1005215 –

回答

6

窗口[ '的eval']在全局範圍內進行操作,eval()函數在局部範圍內進行操作。

從Mozilla的javascript參考:

如果您使用eval函數間接地,經由比EVAL以外的 引用調用它,爲的ECMAScript 5的它在全球範圍內 的作品,而不是本地範圍;這意味着,例如,該函數 聲明創建全局函數,並且被評估的代碼 不能訪問調用它的範圍 內的局部變量。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

3

您的內部函數實際上並沒有捕獲到x的引用,所以它不會直接傳遞給eval

eval通常工作at the local scope等第一次調用成功(因爲本地作用域包含x的聲明)。

但是,如果您以不直接引用eval的方式調用eval,它將在全局範圍內調用它自己,而var x不屬於它,它會失敗。

只是不使用eval。

1

您可以使用Function.prototype.bind()傳遞x退換功能

var f = function() { 
 
    var x = 10; 
 

 
    function y(n) { 
 
     eval(`console.log(${n})`); 
 
     window["eval"](`console.log(${n})`); 
 
    } 
 

 
    return y.bind(this, x) 
 
}; 
 

 
f()();

+1

嗯,這是字符串插值,你甚至不需要爲此綁定,你可以直接在eval語句中插入變量而不使用參數。 'f = function(){var x = 5; return function(){eval(\'console.log($ {x})\')}}' –

1

在全球範圍內window.eval工作。

var variable = 1; 
 

 
(function(){ 
 
    var variable = 100, 
 
     cmd = "++variable"; 
 
    document.write(eval(cmd)+"\n"); // increment local var 100 and output 101 
 
    document.write(window.eval(cmd)+"\n"); // increment global var 1 and output 2 
 
})();