【问题标题】:What are the advantages of using callbacks over strings to encapsulate code in javascript?在javascript中使用回调而不是字符串来封装代码有什么好处?
【发布时间】:2017-06-23 16:04:58
【问题描述】:

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

编辑:

例如:

存储为字符串的代码:

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

存储为函数的代码:

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

【问题讨论】:

  • 你能举个例子,eval 会代替闭包吗?
  • @le_m 查看我的编辑。
  • 你的例子甚至不是关闭
  • 所以,把它称为它是什么,而不是它不是什么。
  • 您确实应该将Strings 视为 Javascript 中的不可变数据,而不是代码。 eval 只是把你带到黑暗的一面。

标签: javascript ecmascript-6 ecmascript-5


【解决方案1】:

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
}

【讨论】:

  • 另外,eval 无法优化,与函数调用相比速度较慢。此外,调试更复杂。而且 IDE 不会检查代码字符串的语法错误。
【解决方案2】:

当您使用字符串时,您不会删除闭包。该函数仍然必须在同一范围内,就好像您直接调用该函数一样。通常,您希望避免使用 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 2012-05-03
    相关资源
    最近更新 更多