前端面試準備1----JS中eval()解析和爲何不要使用eval

  在看別的大牛的博客時,總會提示不要使用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 的解決方案應該獲得充分考慮並優先採用。作用域

相關文章
相關標籤/搜索