使用回调比字符串在javascript中封装代码有什么好处?

时间:2017-06-23 16:04:58

标签: javascript ecmascript-6 ecmascript-5

在javascript中,可以将代码存储为字符串并使用“eval”执行它。另一方面,我们可以将代码表示为进一步执行的函数。为什么在javascript中优先使用'eval'上的闭包?

修改

例如:

代码存储为字符串:

function(x, y, callback){
  if (x > y){
      eval(callback);
  }
}

代码存储为函数:

function(x, y, callback){
  if (x > y){
      callback();
  }
}

2 个答案:

答案 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);