简体   繁体   中英

Clarification required - Passing arguements to functions - Javascript

I have a doubt regarding one of the answers at this link

Do you recommend using semicolons after every statement in JavaScript?

I am providing the particular answer that I need clarification on:

An ambiguous case that breaks in the absence of a semicolon:

 // define a function var fn = function () { //... } // semicolon missing at this line // then execute some code inside a closure (function () { //... })(); 

This will be interpreted as:

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

We end up passing the second function as an argument to the first function and then trying to call the result of the first function call as a function. The second function will fail with a "... is not a function" error at runtime.

My doubt is that how come the second function became the argument of the first function? Because for all I know

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

And not after the {} .

Can someone explicitly explain which ones are the functions and their respective arguments?

I think you are mixing up the parameters in the definition of the function and the arguments passed in when the function is called. The parameters do go in the first parenthesis when you define the function, but arguments go in the second when you call it.

for example:

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

The confusion might be caused by using the term "arguments" for two related but slightly different things:

  • Parameters that are specified in the definition of a function.
  • Arguments that are passed when a function is called.

Since these things are related, people sometimes refer to these two different concepts using the same word sometimes parameters, sometimes arguments. The difference is better explained here: What's the difference between an argument and a parameter?

What OP of the answer means is that when you minify your javascript file, if a function is followed by IIFE without having semicolon between them, it will break.

Now to answer your question:

how come the second function became the argument of the first function?

how do you call a function? You add parenthesis () after it.

In the mentioned case, the code would look like:

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

// i.e.

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

So it calls the function and expects another functions its output.

You can call any function directly by putting () behind it. Just like you call a method. myMethod( arguments ) .

So if you write a function definition and then add () to the end, it immediately gets called:

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

When you call a function, anything between the () will be interpreted as an argument for the function. And since functions can be arguments for other functions, omitting that one ; , makes the second function become the argument of the first.

Such directly called functions are called IIFE: Immediately Invoked Function Expression .

So the following two lines are identical in result:

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

The difference between the two is that function first gets called immediately by adding the () after the definition. And the function second gets called seperately on the next line.

To make a bigger distinction between IIFE functions, they are usually wrapped into an extra set of () to make it more clear that it's a IIFE:

(function(){ ... })( arg ); or even more clear (function(){ ... }( arg )); .

As you many know writing an IIFE like this doesn't work since for a function to be evaluated as an expression it requires extra parentheses

function foo() {

}();

instead it needs to be this

(function foo() {

})();

Well this is not the case when you have already made it an expression by assigning it to a variable like this

let foo = function foo() {

}();

Now as soon as you write a function like the last example but omit the ; then you can fall into the trap of running the first function passing in the second function as you showed in your example.

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

First of all, the function on line 1 is function expression and not function declaration . A function expression followed by a pair of parentheses will be invoked immediately (also known a IIFEs). So, the following code would log Hello World :

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

In your code, the 2nd function is being passed to first function but it's reference is not being stored in any formal parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM