在javascript中,可以将代码存储为字符串并使用“eval”执行它。另一方面,我们可以将代码表示为进一步执行的函数。为什么在javascript中优先使用'eval'上的闭包?
修改
例如:
代码存储为字符串:
function(x, y, callback){
if (x > y){
eval(callback);
}
}
代码存储为函数:
function(x, y, callback){
if (x > y){
callback();
}
}
答案 0 :(得分:3)
eval
本身不会创建闭包,也不会提供封装。它只是一种评估表示为字符串的JavaScript代码的方法。
如果使用eval
执行函数(就像你的例子那样),它不会修改该函数的范围,也不会修改该函数创建的闭包。无论eval
如何,函数总是在它们最初声明的范围内执行,它们总是创建一个闭包(它封装了在该函数中所做的任何声明)。
只涉及范围和eval
的一个小细微差别。如果直接调用eval
,它将使用本地范围。如果间接调用eval
,它将使用全局范围。
来自MDN的示例:
function test() {
var x = 2, y = 4;
console.log(eval('x + y')); // Direct call, uses local scope, result is 6
var geval = eval; // equivalent to calling eval in the global scope
console.log(geval('x + y')); // Indirect call, uses global scope, throws ReferenceError because `x` is undefined
}
答案 1 :(得分:0)
当你使用字符串时,你不能删除封闭。该函数仍然必须与您直接调用函数时的范围相同。通常,您希望避免使用eval,因为它较慢。例如:
function sayHi() {
alert('hi');
function sayHo() {
alert('ho');
}
sayHo()
}
function callAnotherFunctionByString(func) {
eval(func)
}
function callAnotherFunction(func) {
func()
}
// Both of these will work
callAnotherFunctionByString('sayHi()');
callAnotherFunction(sayHi);
// Neither of these will work because the sayHo function is closed off to the sayHi function
callAnotherFunctionByString('sayHo()');
callAnotherFunction(sayHo);