調用eval函數,能夠將其參數做爲javascript程序進行解釋。換句話說,eval能夠把它的參數當作代碼javascript
來執行。java
function f(x) { eval('var y=x'); console.log('y:', y); } f('hello');//y:hello
在這個例子中,eval
將它的string
參數var y=x
做爲一行代碼執行了,在函數f
內部聲明瞭一個局部變量y
。這和安全
function f(x) { var y=x; console.log('y:', y); } f('hello');//y:hello
的執行效果基本相同。函數
容許eval函數干擾做用域,是一個至關錯誤的作法。這種作法會使一段代碼變得難以理解,而且再也不安全。下面這個例子便賦予了外部調用者修改局部變量,改變局部做用域的能力。code
let g = '全局變量' function f(src) { eval(src); console.log('g:', g); } //以上爲源代碼 f("var g= '局部變量'");//g:局部變量 f("var y= '局部變量'");//g:全局變量
當咱們將沒有在源代碼中定義的變量y
傳入eval
函數時,這段代碼執行的結果將變得難以預測。ip
保證eval
函數不影響外部做用域的一個簡單方法是使用嵌套的做用域。ES5的嚴格模式
即是這樣作的。作用域
let g = '全局變量' function f(src) { (()=> eval(src))();//在嵌套做用域中執行eval console.log('g:', g); } //以上爲源代碼 f("var g= '局部變量'");//g:全局變量 f("var y= '局部變量'");//g:全局變量
當函數調用涉及eval
標識符時,能夠稱爲直接調用。此時,被執行的程序(eval的參數)具備徹底訪問調用者局部做用域的權限。string
const g = '全局變量'; function foo() { const g = '局部變量'; console.log(eval('g'));//直接調用,能夠訪問到foo的局部做用域,因此輸出的是局部變量g } foo(); //局部變量
綁定eval
到另外一個變量名,在經過該變量調用eval
,稱之爲間接調用。此時,被執行的程序(eval的參數)失去對局部做用域的訪問能力。利用逗號操做符,
,能夠實現間接調用的簡潔寫法。io
const g = '全局變量'; function foo2() { const g = '局部變量'; cont test = eval; //間接調用,不能訪問函數內部的變量g console.log(test('g')); //全局變量 //間接調用簡潔方式 console.log((0, eval)('g'));//全局變量 }