在這幾個 API 中傳入字符串,老是會弄混它們的區別,因此就寫了篇總結出來,之後弄混淆也好回看javascript
Function、setTimeout、setInterval,傳遞字符串的話,大部分狀況下,與使用 eval() 是相似的java
若是代碼中必須使用 eval() 的話,能夠考慮使用 new Function() 來代替,有一個潛在的好處,就是在 Function 中寫代碼,是在局部函數做用域中運行,因此代碼中任何經過 var 定義的變量都不會自動變成全局變量。這就比如在一個自調用函數中使用 eval()函數
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);";
new Function(jsstring)(); // "2"
jsstring = "var trois = 3; console.log(trois);";
(function () {
eval(jsstring);
}()); // "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 是相同的)ui
(function() {
var local = 1;
eval('local = 3; console.log(local)'); // 3
console.log(local); // 3
})();
(function() {
var local = 1;
Function('console.log(typeof local);') // undefined
})();
複製代碼
setTimeout 和 setInterval 方法傳入字符串會在全局做用域下執行,也能像 Function 同樣避免本地代碼污染spa
(function() {
var local = 1;
setTimeout('console.log(typeof local);') // undefined
setInterval('console.log(typeof local);') // undefined
})();
複製代碼
注意:setTimeout 和 setInterval 方法傳入帶有 var 聲明的字符串的話,會在全局做用域下進行聲明code
(function() {
setTimeout('var a = 123;console.log(window.a);') // 123
})();
複製代碼