函数调用中“()”的含义是什么?

时间:2010-09-04 07:38:07

标签: javascript

现在,我通常使用()调用一个函数(不需要参数),如下所示:

myFunction(); //there's empty parens

除了jQuery调用,我可以逃脱:

$('#foo').bind('click', myFunction); //no parens

精细。但最近我在SO上看到了这条评论here

“考虑使用setTimeout(monitor, 100);代替setTimeout('monitor()', 100); .Eval是邪恶的:)”

糟糕!我们真的eval()在这里输了一个字符串吗?我想我并不真正理解“调用”函数的意义和含义。有关调用和引用函数的真正规则是什么?

4 个答案:

答案 0 :(得分:44)

在JavaScript函数中是第一类对象。这意味着您可以将函数作为参数传递给函数,或者将它们视为变量。

假设我们正在谈论一个函数hello

function hello() {
    alert('yo');
}

当我们写简单时

hello

我们指的是不执行它内容的函数。但是当我们在函数名称之后添加parens ()时,

hello()

然后我们实际上调用了将在屏幕上警告“你”的功能。

jQuery中的bind方法接受事件类型(字符串)和函数作为其参数。在您的示例中,您将传递类型 - “单击”和实际函数作为参数。

你见过Inception吗?考虑这个可能使事情更清晰的人为例子。由于函数是JavaScript中的第一类对象,我们可以在函数内传递和返回函数。因此,让我们创建一个在调用时返回函数的函数,并且返回的函数在调用时也会返回另一个函数。

function reality() {
    return function() {
        return function() {
            alert('in a Limbo');
        }
    };
}

此处reality是一个函数,reality()是一个函数,reality()()也是一个函数。但是reality()()()不是函数,而只是undefined因为我们没有从最里面的函数返回一个函数(我们没有返回任何东西)。

因此,对于reality函数示例,您可以将以下任何内容传递给jQuery的bind。

$('#foo').bind('click', reality);
$('#foo').bind('click', reality());
$('#foo').bind('click', reality()());

答案 1 :(得分:7)

您的jQuery bind示例与setTimeout(monitor, 100);类似,您将函数对象的引用作为参数传递。

应避免将字符串传递给setTimeout / setInterval方法,原因与在不必要时应避免evalFunction构造函数相同。

作为字符串传递的代码将在全局执行上下文中进行评估和运行,这可以为您提供“范围问题”,请考虑以下示例:

// a global function
var f = function () {
  alert('global');
};

(function () {
  // a local function
  var f = function() {
    alert('local');
  };

  setTimeout('f()', 100); // will alert "global"
  setTimeout(f, 100);     // will alert "local"
})();

上例中的第一个setTimeout调用将执行全局f函数,因为已计算的代码无法访问匿名函数的本地词法范围。

如果在第二个setTimeout调用中将函数对象的引用传递给setTimeout方法 - 将在当前作用域中引用完全相同的函数。

答案 2 :(得分:3)

你在jQuery示例中没有像在第二个setTimeout示例中那样做 - 在你的代码中传递函数并绑定click事件。

在第一个setTimout示例中,monitor函数被传入并且可以直接调用,在第二个中,sting monitor()被传入并且需要{{1 }}编

传递函数时,使用函数名称。调用它时,您需要使用eval

Eval将调用传入的内容,因此成功调用函数需要()

答案 3 :(得分:2)

首先,“()”不是函数名称的一部分。 它是用于进行函数调用的语法。

首先,通过使用函数声明将函数绑定到标识符名称:

function x() {
    return "blah";
}

...或使用函数表达式:

var x = function() {
    return "blah";
};

现在,只要您想运行此功能,就可以使用parens:

x();

setTimeout函数接受函数的两者和标识符,或者接受字符串作为第一个参数...

setTimeout(x, 1000);
setTimeout("x()", 1000);

如果您提供标识符,则它将作为函数调用。 如果你提供一个字符串,那么它将被评估(执行)。

第一种方法(提供标识符)是首选......