在这几个 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
})();
复制代码