eval翻譯:是evaluate习贫,評(píng)估略贮,評(píng)價(jià)的意思蕴忆。
eval的重點(diǎn)在于eval函數(shù)名賦值給變量之后,它的作用域可能發(fā)生的變化慰丛。參考代碼段3
w3school中eval的定義:eval(string) 函數(shù)可計(jì)算所傳字符串string卓囚,并執(zhí)行其中的的 JavaScript 代碼,代碼是可執(zhí)行語句或者字符串都會(huì)被執(zhí)行诅病。
eval('window.console.log("LBJ")');//LBJ
eval(window.console.log("LBJ"));//LBJ
window.console.log("LBJ");//LBJ
//三條語句輸出的結(jié)果是一樣的
下面參考其他博客的總結(jié):
在看別的大牛的博客時(shí)哪亿,總會(huì)提示不要使用eval粥烁,一直沒有深入研究為什么,總以為是安全性問題蝇棉,也沒有去研究eval的其他的注意事項(xiàng)讨阻,最近在看“JavaScript秘密花園”博客時(shí),碰到這個(gè)問題篡殷,參考并做了一些總結(jié)变勇。
首先,eval函數(shù)的作用是在當(dāng)前作用域中
執(zhí)行一段JavaScript代碼字符串贴唇。
如下代碼段1:
//代碼段1
var foo = 1;
function test() {
var foo = 2;
eval('foo = 3');
return foo;
}
test(); // 3
foo; // 1
函數(shù)test里面調(diào)用eval執(zhí)行foo=3,修改了test()函數(shù)的變量foo搀绣,并不會(huì)改變?nèi)謋oo的值。
但是 eval 只在被直接調(diào)用并且調(diào)用函數(shù)就是 eval 本身時(shí)戳气,才在當(dāng)前作用域中執(zhí)行
链患,如何理解這句話呢?
以下代碼段2就不屬于對(duì)于eval的直接調(diào)用了
代碼段2如下:
//代碼段2
var foo = 1;
function test() {
var foo = 2;
var bar = eval; //這里將bar變量指向了eval函數(shù)的引用
bar('foo = 3');
return foo;
}
test(); // 2
foo; // 3
上面的代碼等價(jià)于在全局作用域中調(diào)用 eval,和下面兩種寫法(代碼段3)效果一樣:
代碼段3:
//代碼段3
// 寫法一:直接調(diào)用全局作用域下的 foo 變量
var foo = 1;
function test() {
var foo = 2;
window.foo = 3;
return foo;
}
test(); // 2
foo; // 3
// 寫法二:使用 call 函數(shù)修改 eval 執(zhí)行的上下文為全局window作用域
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 的場(chǎng)景都有不使用 eval 的解決方案麻捻。
安全問題
eval 也存在安全問題,因?yàn)樗鼤?huì)執(zhí)行任意傳給它的代碼呀袱, 在代碼字符串未知或者是來自一個(gè)不信任的源時(shí)贸毕,絕對(duì)不要使用 eval 函數(shù)。
結(jié)論
絕對(duì)不要使用 eval夜赵,任何使用它的代碼都會(huì)在它的工作方式明棍,性能和安全性方面受到質(zhì)疑。 如果一些情況必須使用到 eval 才能正常工作寇僧,首先它的設(shè)計(jì)會(huì)受到質(zhì)疑摊腋,這不應(yīng)該是首選的解決方案, 一個(gè)更好的不使用 eval 的解決方案應(yīng)該得到充分考慮并優(yōu)先采用嘁傀。