eval、setTimeout、setInterval、Function 传入字符串区别

999 阅读1分钟

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