这两个JavaScript函数有什么区别?

4

在学习JavaScript的过程中,我遇到了两种类型的函数。我尝试将它们按照我的理解列举如下。

function example(arg1, arg2) { //code to do stuff here }

并且

thing.method(function(arg) {
  //code to do stuff here
});

我的想法是第一种情况是创建一个名为example的函数,它需要两个参数并且在花括号中执行一些操作。只要在范围内,我相信该函数可以被调用和使用(我认为这是正确的词吗?)。

在第二种情况下,我感到困惑。我的想法是我们有一个东西(数组、对象等),一个方法被调用(foreach、map等),然后我卡住了。有一个没有名称的函数吗?需要一个参数,并在花括号内执行一些操作。假设这个东西是一个数组,我们调用了foreach,那么函数括号内的内容将对每个元素进行操作?为什么我要使用这个而不是像第一个函数那样创建一个我可以直接调用的函数呢?

我为什么不能只说:

function example(arg) { //stuff }
thing.method(example(arg));

我可能对一些事情有所误解,能否有人为我澄清一下?


1
你可以这样说:function example(arg) {}; thing.method(example); 第二个例子基本上是将函数作为thing方法的第一个参数发送。对于forEach示例,Array.forEach(function(){}); 将在数组的每个元素上运行该函数,因为forEach基本上意味着“在我的数组中对每个元素使用传递给forEach的第一个参数”。 - Shilly
1
这可以通过设计模式完成。请参见 https://scotch.io/bar-talk/4-javascript-design-patterns-you-should-know 获取更多信息。请注意,这不是模式的详尽列表;例如它不包括工厂模式。 - IronAces
2
你在第一个问题上是正确的。第二个问题有点棘手。它被称为回调函数。你正在将一个函数(匿名函数,正如你所说)传递给另一个函数(thing.method),该函数将在其代码的某个位置回调该匿名函数。 - Leandro
今天的关键词是“回调函数”。另外,只要你有一个对函数的引用(无论你所说的作用域是什么),就可以调用该函数,而不是只在作用域内调用。该函数将保留其作用域(闭包)。 - Thomas
2个回答

1
thing.method(function(arg) {
  //code to do stuff here
});

这里使用的是所谓的匿名函数。就像你说的一样,它没有名称。它作为参数传递给thing.method()thing.method()的函数体将使用此函数,例如:

thing: {
    method: function(callback) {
        //...
        callback();
        //...
    }
};

你不能将此写为


function example(arg) { /* stuff */ }
thing.method(example(arg));

在这个例子中,您将example(arg)的返回值传递给了thing.method(),而不是函数本身。但是,您可以像这样编写它:将函数本身作为参数传递给thing.method()
function example(arg) { /* stuff */ }
thing.method(example);

现在,你可以想象method()设置一些变量并将其传递给你传入的函数,例如:
thing: {
    method: function(callback) {
        var foo = "bar";
        //...
        callback(foo);
        //...
    }
};

谢谢你的回答,非常有帮助! - user6004361

0

你的第一个函数example是一个命名函数,可以在整个JS程序中重复使用。它具有全局作用域。要使用它,您需要调用它,如下所示:

example(value1, value2);

这将把value1value2发送到函数中,并通常使用这些值执行某些操作。通常该函数会返回一个值。

第二个函数既是匿名函数又是回调函数。它是匿名的,因为它没有名称,而且回调函数只有在事件发生时才会被调用。你几乎总是与事件(如clickhover等)一起使用这些函数。

一个很好的例子可能是,在你的示例中,你的方法是thing上的点击事件。当用户点击thing时,匿名函数就会被触发。作用域不是全局的,它只能在点击事件内部访问。

// jQuery callback on a click event
$("#button-in-your-program").click(function() {
  console.log("Your callback function worked");
});

与所有这些相关的另一个主题是闭包。闭包是每次调用函数时创建的词法作用域。大多数情况下,您并不真正考虑它。但是当您将一个函数嵌套在另一个函数中时,它变成了一个重要的概念。例如,当子函数引用其父函数中的变量时,使用闭包将变量的值提供给子函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接