在这几个 API 中传入字符串,总是会弄混它们的区别,所以就写了篇总结出来,以后弄混淆也好回看
Function、setTimeout、setInterval,传递字符串的话,大部分情况下,与使用 eval() 是类似的
Function
如果代码中必须使用 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 是相同的)
(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
setTimeout 和 setInterval 方法传入字符串会在全局作用域下执行,也能像 Function 一样避免本地代码污染
(function() {
var local = 1;
setTimeout('console.log(typeof local);') // undefined
setInterval('console.log(typeof local);') // undefined
})();
注意:setTimeout 和 setInterval 方法传入带有 var 声明的字符串的话,会在全局作用域下进行声明
(function() {
setTimeout('var a = 123;console.log(window.a);') // 123
})();