在看別的大牛的博客時,總會提示不要使用eval,一直沒有深刻研究爲何,總覺得是安全性問題,也沒有去研究eval的其餘的注意事項,安全
最近在看「JavaScript祕密花園」博客時,碰到這個問題,參考並作了一些總結。函數
首先,eval函數的做用是在當前做用域中執行一段JavaScript代碼字符串,以下代碼段1:性能
//代碼段1
var foo = 1; function test() { var foo = 2; eval('foo = 3'); return foo; } test(); // 3 foo; // 1
可是 eval
只在被直接調用而且調用函數就是 eval
自己時,纔在當前做用域中執行,如何理解這句話呢,以上的代碼就是對紅色背景部分的描述,spa
如下代碼段2就不屬於對於eval的直接調用了,代碼段2以下:.net
//代碼段2 var foo = 1; function test() { var foo = 2; var bar = eval; bar('foo = 3'); return foo; } test(); // 2 foo; // 3
上面的代碼等價於在全局做用域中調用 eval
,和下面兩種寫法(代碼段3)效果同樣:設計
//代碼段3 // 寫法一:直接調用全局做用域下的 foo 變量 var foo = 1; function test() { var foo = 2; window.foo = 3; return foo; } test(); // 2 foo; // 3 // 寫法二:使用 call 函數修改 eval 執行的上下文爲全局做用域 var foo = 1; function test() { var foo = 2; eval.call(window, 'foo = 3'); return foo; } test(); // 2 foo; // 3
在任何狀況下咱們都應該避免使用 eval
函數。99.9% 使用 eval
的場景都有不使用 eval
的解決方案。code
eval
定時函數 setTimeout
和 setInterval
均可以接受字符串做爲它們的第一個參數。 這個字符串老是在全局做用域中執行,所以 eval
在這種狀況下沒有被直接調用。blog
eval
也存在安全問題,由於它會執行任意傳給它的代碼, 在代碼字符串未知或者是來自一個不信任的源時,絕對不要使用 eval
函數。ip
絕對不要使用 eval
,任何使用它的代碼都會在它的工做方式,性能和安全性方面受到質疑。 若是一些狀況必須使用到 eval
才能正常工做,首先它的設計會受到質疑,這不該該是首選的解決方案, 一個更好的不使用 eval
的解決方案應該獲得充分考慮並優先採用。作用域