eval 函數(shù)會在當(dāng)前作用域中執(zhí)行一段 JavaScript 代碼字符串。
var foo = 1;
function test() {
var foo = 2;
eval('foo = 3');
return foo;
}
test(); // 3
foo; // 1
但是 eval 只在被直接調(diào)用并且調(diào)用函數(shù)就是 eval 本身時(shí),才在當(dāng)前作用域中執(zhí)行。
var foo = 1;
function test() {
var foo = 2;
var bar = eval;
bar('foo = 3');
return foo;
}
test(); // 2
foo; // 3
譯者注:上面的代碼等價(jià)于在全局作用域中調(diào)用 eval,和下面兩種寫法效果一樣:
// 寫法一:直接調(diào)用全局作用域下的 foo 變量
var foo = 1;
function test() {
var foo = 2;
window.foo = 3;
return foo;
}
test(); // 2
foo; // 3
// 寫法二:使用 call 函數(shù)修改 eval 執(zhí)行的上下文為全局作用域
var foo = 1;
function test() {
var foo = 2;
eval.call(window, 'foo = 3');
return foo;
}
test(); // 2
foo; // 3
在任何情況下我們都應(yīng)該避免使用 eval 函數(shù)。99.9% 使用 eval 的場景都有不使用 eval 的解決方案。
定時(shí)函數(shù) setTimeout 和 setInterval 都可以接受字符串作為它們的第一個(gè)參數(shù)。
這個(gè)字符串總是在全局作用域中執(zhí)行,因此 eval 在這種情況下沒有被直接調(diào)用。
eval 也存在安全問題,因?yàn)樗鼤?zhí)行任意傳給它的代碼,
在代碼字符串未知或者是來自一個(gè)不信任的源時(shí),絕對不要使用 eval 函數(shù)。
絕對不要使用 eval,任何使用它的代碼都會在它的工作方式,性能和安全性方面受到質(zhì)疑。
如果一些情況必須使用到 eval 才能正常工作,首先它的設(shè)計(jì)會受到質(zhì)疑,這不應(yīng)該是首選的解決方案,
一個(gè)更好的不使用 eval 的解決方案應(yīng)該得到充分考慮并優(yōu)先采用。