JavaScript探秘:eval()是“魔鬼”

eval()可以干擾作用域鏈
服務器君一共花費了222.265 ms進行了7次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

如果你現在的代碼中使用了eval(),記住該咒語“eval()是魔鬼”。此方法接受任意的字符串,并當作JavaScript代碼來處理。當有問題的代碼是事先知道的(不是運行時確定的),沒有理由使用eval()。如果代碼是在運行時動態生成,有一個更好的方式不使用eval而達到同樣的目標。例如,用方括號表示法來訪問動態屬性會更好更簡單:

// 反面示例
var property = "name";
alert(eval("obj." + property));

// 更好的
var property = "name";
alert(obj[property]);

使用eval()也帶來了安全隱患,因為被執行的代碼(例如從網絡來)可能已被篡改。這是個很常見的反面教材,當處理Ajax請求得到的JSON 相應的時候。在這些情況下,最好使用JavaScript內置方法來解析JSON相應,以確保安全和有效。若瀏覽器不支持JSON.parse(),你可以使用來自JSON.org的庫。

同樣重要的是要記住,給setInterval(), setTimeout()和Function()構造函數傳遞字符串,大部分情況下,與使用eval()是類似的,因此要避免。在幕后,JavaScript仍需要評估和執行你給程序傳遞的字符串:

// 反面示例
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);

// 更好的
setTimeout(myFunc, 1000);
setTimeout(function () {
   myFunc(1, 2, 3);
}, 1000);

使用新的Function()構造就類似于eval(),應小心接近。這可能是一個強大的構造,但往往被誤用。如果你絕對必須使用eval(),你可以考慮使用new Function()代替。有一個小的潛在好處,因為在新Function()中作代碼評估是在局部函數作用域中運行,所以代碼中任何被評估的通過var 定義的變量都不會自動變成全局變量。另一種方法來阻止自動全局變量是封裝eval()調用到一個即時函數中。

考慮下面這個例子,這里僅un作為全局變量污染了命名空間。

console.log(typeof un);    	// "undefined"
console.log(typeof deux); 	// "undefined"
console.log(typeof trois); 	// "undefined"

var jsstring = "var un = 1; console.log(un);";
eval(jsstring); 			// logs "1"

jsstring = "var deux = 2; console.log(deux);";
new Function(jsstring)(); 	// logs "2"

jsstring = "var trois = 3; console.log(trois);";
(function () {
   eval(jsstring);
}()); // logs "3"

console.log(typeof un); 	// number
console.log(typeof deux); 	// "undefined"
console.log(typeof trois); 	// "undefined"

另一間eval()和Function構造不同的是eval()可以干擾作用域鏈,而Function()更安分守己些。不管你在哪里執行 Function(),它只看到全局作用域。所以其能很好的避免本地變量污染。在下面這個例子中,eval()可以訪問和修改它外部作用域中的變量,這是 Function做不來的(注意到使用Function和new Function是相同的)。

(function () {
   var local = 1;
   eval("local = 3; console.log(local)"); // logs "3"
   console.log(local); // logs "3"
}());

(function () {
   var local = 1;
   Function("console.log(typeof local);")(); // logs undefined
}());

延伸閱讀

此文章所在專題列表如下:

  1. 我們應該如何去了解JavaScript引擎的工作原理
  2. JavaScript探秘:編寫可維護的代碼的重要性
  3. JavaScript探秘:謹慎使用全局變量
  4. JavaScript探秘:var預解析與副作用
  5. JavaScript探秘:for循環(for Loops)
  6. JavaScript探秘:for-in循環(for-in Loops)
  7. JavaScript探秘:Prototypes強大過頭了
  8. JavaScript探秘:eval()是“魔鬼”
  9. JavaScript探秘:用parseInt()進行數值轉換
  10. JavaScript探秘:基本編碼規范
  11. JavaScript探秘:函數聲明與函數表達式
  12. JavaScript探秘:命名函數表達式
  13. JavaScript探秘:調試器中的函數名
  14. JavaScript探秘:JScript的Bug
  15. JavaScript探秘:JScript的內存管理
  16. JavaScript探秘:SpiderMonkey的怪癖
  17. JavaScript探秘:命名函數表達式替代方案
  18. JavaScript探秘:對象Object
  19. JavaScript探秘:原型鏈 Prototype chain
  20. JavaScript探秘:構造函數 Constructor
  21. JavaScript探秘:可執行的上下文堆棧
  22. 執行上下文其一:變量對象與活動對象
  23. 執行上下文其二:作用域鏈 Scope Chains
  24. 執行上下文其三:閉包 Closures
  25. 執行上下文其四:This指針
  26. JavaScript探秘:強大的原型和原型鏈
  27. JavaScript函數其一:函數聲明
  28. JavaScript函數其二:函數表達式
  29. JavaScript函數其三:分組中的函數表達式
  30. JavaScript函數其四:函數構造器
  31. JavaScript變量對象其一:VO的聲明
  32. JavaScript變量對象其二:VO在不同的執行上下文中
  33. JavaScript變量對象其三:執行上下文的兩個階段
  34. JavaScript變量對象其四:關于變量
  35. JavaScript變量對象其五:__parent__ 屬性
  36. JavaScript作用域鏈其一:作用域鏈定義
  37. JavaScript作用域鏈其二:函數的生命周期
  38. JavaScript作用域鏈其三:作用域鏈特征
  39. JavaScript閉包其一:閉包概論
  40. JavaScript閉包其二:閉包的實現
  41. JavaScript閉包其三:閉包的用法

本文地址:http://www.824886.live/librarys/veda/detail/1627,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.824886.live/librarys/veda/detail/1627

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏。

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《JavaScript高級程序設計(第2版)》 尼古拉斯·澤卡斯(Nicholas C.Zakas) (作者), 李松峰 (譯者), 曹力 (譯者)

《JavaScript高級程序設計(第2版)》在上一版基礎上進行了大幅度更新和修訂,融入了近幾年來JavaScript應用發展的最新成果,幾乎涵蓋了所有需要理解的重要概念和最新的JavaScript應用成果。從頗具深度的JavaScript語言基礎到作用域(鏈),從引用類型到面向對象編程,從極其靈活的匿名函數到閉包的內部機制,從瀏覽器對象模型(BOM)、文檔對象模型(DOM)到基于事件的Web腳本設計,從XML(E4X)到Ajax及JSON,從高級前端開發技術到前沿的客戶端存儲,從最佳編程實踐到即將成為現實的API,直至JavaScript未來的發展,全景式地展示了JavaScript高級程序設計的方方面面。

更多計算機寶庫...

云南快乐十分走势一定牛 微乐长春家乡麻将 点中一码不是梦2020 股市分析文章 单机波克斗地主旧版本 2020年中超联赛开赛时间 2人麻将规则和玩法 初中生打字兼职一单一结 多人玩的棋牌? 服装搭配师资格证 天开眼麻将手机版下