需要澄清-将争论传递给函数-Javascript

时间:2018-08-03 13:55:25

标签: javascript

我对此链接中的答案之一有疑问

Do you recommend using semicolons after every statement in JavaScript?

我提供了我需要澄清的特定答案:

  

一个模棱两可的情况,在没有分号的情况下会中断:

// define a function
var fn = function () {
    //...
} // semicolon missing at this line

// then execute some code inside a closure
(function () {
    //...
})();
     

这将解释为:

var fn = function () {
    //...
}(function () {
    //...
})();
     

我们最终将第二个函数作为参数传递给第一个   函数,然后尝试调用第一个函数调用的结果   作为一个功能。第二个功能将失败,并显示“ ...不是   功能”错误。

我的疑问是第二个功能为何成为第一个功能的参数?因为据我所知

function myFunc(/*argument goes here*/){}

而不是在{}之后。

有人可以明确解释这些函数是什么以及它们各自的参数吗?

5 个答案:

答案 0 :(得分:2)

我认为您正在混淆函数定义中的参数和调用函数时传递的参数。定义函数时,参数 do 放在第一个括号中,而当您调用时,参数放在第二个括号中。

例如:

let test = function(arg){               // define parameters here
       console.log("called with", arg)  // use arguments here
}
("hello")                               //pass in arguments here

混淆可能是由于对两个相关但略有不同的事物使用术语“参数”引起的:

  • 在函数定义中指定的参数。
  • 调用函数时传递的参数。

由于这些事情是相关的,因此人们有时会使用相同的单词(有时称为参数,有时称为参数)来引用这两个不同的概念。可以在这里更好地解释差异:What's the difference between an argument and a parameter?

答案 1 :(得分:0)

答案的OP表示,当您最小化javascript文件时,如果IIFE后接一个函数而它们之间没有分号,则它将中断。

现在回答您的问题:

  

第二个函数为何成为第一个函数的参数?

您如何调用函数?在其后加上括号()

在上述情况下,代码如下:

var fn = function () { ... }(function () { ... })();

// i.e.

var fn = function() { ... }(...)();

因此它调用该函数并期望另一个函数输出。

答案 2 :(得分:0)

可以通过在其后面放置()来直接调用任何函数。就像您调用方法一样。 myMethod( arguments )

因此,如果您编写函数定义,然后在末尾添加(),则会立即调用它:

var fn = function() {
  console.log( 'function executing' );
}();

调用函数时,()之间的任何内容都将解释为该函数的参数。而且由于函数可以作为其他函数的参数,因此省略了一个;,会使第二个函数成为第一个函数的参数。

直接调用的函数称为IIFE:Immediately Invoked Function Expression

因此以下两行的结果相同:

var first = function( arg ) {
  console.log( "arg: " + arg );
}( "first argument" );

var second = function( arg ) {
  console.log( "arg: " + arg );
};
second( "first argument" );

两者之间的区别在于,首先在定义后添加()来立即调用该函数。第二个函数在下一行分别调用。

要在IIFE函数之间进行更大的区分,通常将它们包装在一组额外的()中,以更清楚地表明它是IIFE:

(function(){ ... })( arg );或更清晰的(function(){ ... }( arg ));

答案 3 :(得分:0)

众所周知,编写这样的IIFE是行不通的,因为要将函数作为表达式求值需要额外的括号

function foo() {

}();

相反,必须是这个

(function foo() {

})();

当您已经通过将表达式赋给这样的变量来使其成为表达式时,情况并非如此

let foo = function foo() {

}();

现在,只要编写与上一个示例类似的函数,但省略;,就可以陷入运行第一个函数的陷阱,如第二个示例所示。 >

let foo = function foo() {
    //...
}(function () {
    //...
})();

答案 4 :(得分:0)

首先,第1行上的函数是函数表达式,而不是函数声明。将立即调用后跟一对括号的函数表达式(也称为IIFE)。因此,以下代码将记录 Hello World

var fn = function(a){ console.log(a) }("Hello World");

在您的代码中,第二个函数被传递给第一个函数,但其​​引用没有存储在任何形式参数中。