本文章記錄本人在學習 JavaScript 中看書理解到的一些東西,加深記憶和而且整理記錄下來,方便以後的複習。瀏覽器
若是在代碼中使用了eval()
,請記住一句話:「eval()
是一個魔鬼」。該函數能夠將任意的字符串當作一個js
代碼來執行。當須要討論的代碼是預先編譯好了(不是在動態運行時候決定),是沒有理由使用eval()
的。例如,若是你知道點表示法,可是不知道下表表示法的狀況(下面一個栗子)。安全
eval("myValue = myObject." + myKey + ";");
而不是這樣寫(下面一個栗子)。網絡
myValue = MyObject[myKey];
使用eval()
是有一些安全隱患的,由於這樣作有可能執行被篡改過的代碼(例如來自網絡的代碼)。這是在處理來自一個Ajax
請求的JSON
響應時候常見的反模式。在那些情景下,最好是使用瀏覽器內置的方法來解析JSON
請求,以確保安全性和有效性。函數
還有eval()
函數還減弱了應用程序的安全性,由於他給被請求的文本賦予了太多的權力,並且就像with
語句執行的方式同樣,它下降了語言的性能。性能
在編寫js
特效的時候,會經常使用setTimeout、setInterval()
方法。要牢記使用這些構造函數來傳遞參數,在大部分狀況下,會致使相似eval()
的隱患,所以應該也儘可能避免使用這些函數。(下面一個栗子)學習
// bad setTimeout("myFunc()", 1000); setInterval("myFunc(1, 2, 3)", 1000); // good setTimeout(myFunc, 1000); setInerval(function(){ myFunc(1, 2, 3); }, 1000);
使用new Function()
構造函數和eval()
是比較相似的,所以該函數的使用也須要十分當心。該函數是一個功能強大的函數,可是一般容易被誤用。若是必定要使用eval()
的話,能夠考慮是new Function()
來代替eval()
。這樣作的一個潛在的好處就是因爲在new Function()
中的代碼將在局部變量函數空間中運行,所以代碼中任何採用var
定義的變量不會自動成爲全局變量(下面一個栗子)。code
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); // 1 jsstring = "var deux = 2; console.log(deux);" eval(jsstring); // 2 jsstring = "var deux = 2; console.log(deux);" (function(){ eval(jsstring); }()); // 3 console.log(typeof un); // number console.log(typeof deux); // undefined console.log(typeof trois); // undefined
還有就是eval()
是會影響到做用域鏈的,而Function
更像一個沙盒。不管在那裏執行Function
,它都僅僅能看到全局做用域。所以對局部變量的影響比較小(下面一個栗子)。ip
(function(){ var local = 1; eval("local = 3; console.log(local)"); console.log(local); // 3 }()); (function(){ var local = 1; Function("console.log(typeof local);")(); // undefined }());
來自MDN:在嚴格模式下 eval 僅僅爲被運行的代碼建立變量, 因此 eval 不會影響到名稱映射到外部變量或者其餘局部變量(下面一個栗子)。作用域
var x = 17; var evalX = eval("'use strict'; var x = 42; x"); assert(x === 17); assert(evalX === 42);
更多的詳細內容:嚴格模式 MDN字符串
最後,若是文章有什麼錯誤和疑問的地方,請指出。與sf各位共勉!