表达式 eval(function(){ } ()) 在 javascript 中做了什么?

What does the expression eval(function(){ } ()) do in javascript?

我在网页上找到了这个脚本:

eval(function(a, b, c, d, e, f) {
    //do some thing here and return value
}(val1, val2, val3, val4, val5, {}))

你知道上面的表达式到底是做什么的吗?

eval 方法实际上用于在执行 eval 语句后立即执行脚本。它可以执行 string 格式的脚本。就像下面 -

eval("console.log('hello world')")

在你的情况下,实际上只是在执行该语句后立即执行脚本。

这有两件事。

  1. 创建一个 anonymous function 并执行它。
  2. eval函数的结果。

这是一个简化的例子。

eval(
  function(a) {
    let str = a + ' world'
    let toEval = 'console.log("' + str + '")'
    // the string is now -> 'console.log("hello world")'
    return toEval
  }('hello')
)

定义一个接受字符串、添加“world”并创建代码作为新字符串的函数,然后 returns 它。这个函数没有nameanonymous.

也是

执行带有参数 hello 的函数。

然后使用eval.

执行返回的代码(字符串形式)

让我们一个一个地打开包装,首先是里面的部分

function(a, b, c, d, e, f) {
    //do some thing here and return value
}(val1, val2, val3, val4, val5, {})

事实上,让我们进一步简化它

(function() { //takes no paremeters
    console.log("this was executed");
}())//no parameters given here

这称为 an immediately invoked function expression 或通常简称为 IIFE。这很无聊,老实说,名称就是完整的描述,但让我改一下 - 这是一个声明然后立即执行的函数。这是由最后的 () 括号完成的——这正是您执行函数的方式,例如 parseInt()。在这个简单的例子中,它只是简单地将一些东西打印到控制台并完成。

然而,它是一个普通函数,它可以做任何你想做的事情,包括接受参数:

(function(param1, param2) { //takes two parameters
    console.log("this was executed with parameters", param1, param2);
}("hello", "world"))//these are passed to the function

所以,你可以做更多的事情。您甚至可以 return 一个值,传递给函数的参数可以是变量:

var someVariable = "hello";
var anotherVariable = "world";

var resultFromIIFE = (function(param1, param2) { //takes two parameters
    console.log("this was executed with parameters", param1, param2);
    return param1 + param2;
}(someVariable, anotherVariable));

console.log(resultFromIIFE);

所以,希望这能清理内部部分。我会回来的。

至于 eval - 它需要一个 string 并将其作为 JavaScript code.

eval("console.log('this comes from eval()')");


var evalCanReturnResults = eval("1 + 2");
console.log(evalCanReturnResults);


var a = 3;
var b = 4;
var evalCanUseVariables = eval("a + b");

console.log(evalCanUseVariables);

这是 eval 的快速速成课程。理解它可以接受任意字符串并将其作为 JS 执行就足够了。

因此,如果我们将两者放在一起,内部 IIFE 很可能会动态生成一些代码供 eval 执行。例如,你可以有像::

这样的东西

eval(function(limit, toPrint) {
    return "for (var i = 0; i < " + limit + "; i++) { console.log('" + toPrint + "') }"
}(3, "foo"))

这将生成一个带有指定参数的 for 循环并执行它。