Nuances of Function Expressions in JavaScript

The name Function Expression is given for a reason. What it really means is that such functions are part of an expression.

For example, we can add some string and an anonymous function:

let str = 'str' + function() {return 2;}; console.log(str); // выведет 'strfunction() {return 2;}'

Why do we see such a strange result and not the number 3? Because the second term is not the result of the function, but its source code (after all, we did not invoke this function, but simply wrote it).

That is, the name function expression means that such a function takes part in some expression.

Assignment to a variable is also an expression:

let func = function() { console.log('!'); };

You can also, for example, pass a function as an alert parameter and it will print its source code to the console - this will also be considered as an expression:

console.log(function() {return 2;});

Why this is important: because the difference between Function Declaration and Function Expression is not at all that the first function is created with a name, and the second one initially has no name. This is not true.

An example. Here we have a function without a name, but it does not participate in any expression (that is, no actions are performed with it, speaking in a simple way):

/* This function will be a Function Declaration, but with a syntax error: */ function() { console.log('!'); }

This code will give an error! Why: since the function does not participate in any expression, the browser considers it as a Function Declaration, but does not find its name and generates an error.

To make the error disappear, you need to force the function to become part of some expression. For example, let's write the operation + before it:

+function() { // this code is correct console.log('!'); };

How it works: by itself, the operation + does nothing, it's the same as writing instead of the number 3 the number +3 - valid, but nothing does not change.

But in the case of a function, it changes. Now our function is not just written, but participates in the expression. Therefore, there will be no error now. There will also be no result of the function execution, because we just wrote it, but did not call it.

Instead of +, you can write whatever you want. For example:

-function() { // this code is correct console.log('!'); }; !function() { // this code is correct console.log('!'); };

You can also put our function in parentheses, in this case it will also become a function expression:

(function() { // this code is correct console.log('!'); });

Determine if the presented function is a Function Declaration or a Function Expression:

function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

let func = function() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

+function() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

!function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

-function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

1 + function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

(function func() { console.log('!'); })

Determine if the presented function is a Function Declaration or a Function Expression:

console.log( function() { console.log('!'); } );

Function has name, but is Function Expression

Let's now make a function that will have a name, but it will be a Function Expression, because it participates in the expression:

+function func() { console.log('!'); }

It is interesting that by the name func we will not be able to refer to our function, this will lead to an error:

+function func() { console.log('!'); } func(); //!! throws an error

To be able to call our function, we need to assign it to some variable:

let test = function func() { console.log('!'); }; test(); // shows '!'

Once again: a function that is a function expression cannot be called by its name. Such a function can only be called using the variable in which this function was written.

But nevertheless, a function expression can have a function name, it will be syntactically correct. Why this is necessary, we will understand in the next lessons.

Summary

To summarize: functions are Function Declaration or Function Expression not because they have a name or not, but because they are members of expressions or not.

As you saw above, a function without a name can be treated as a Function Declaration, and a function with a name can be a Function Expression.

How to check the type of a function

In the tasks below, you will need to define a function defined as a Function Declaration or Function Expression.

In simple cases, this is not difficult to do visually. But how do you check that you did it right? Use the difference between Function Declaration and Function Expression: the former can be called above their definition, while the latter cannot.

Let's say we have such a function:

let test = function() { console.log('!'); }

Let's invoke this function before it's defined:

test(); // throws an error to the console, that means it is Function Expression let test = function() { console.log('!'); }

Here is another example:

func(); // shows '!', it is Function Declaration function func() { console.log('!'); }

Let's put a plus sign in front of our function:

func(); // throws an error to the console, it is Function Expression +function func() { console.log('!'); }

Since the function above is a Function Expression and it is not assigned to any variable, there is no way to call it, because it will not be available by the name func.

Determine if the presented function is a Function Declaration or a Function Expression:

let test = function func() { console.log('!'); }

Determine if the presented function is a Function Declaration and a Function Expression:

console.log( function func() { console.log('!'); } );

Determine if the presented function is a Function Declaration and a Function Expression:

+function func() { console.log('!'); }

Determine if the presented function is a Function Declaration and a Function Expression:

function func() { console.log('!'); }

More complicated nuances

Let's consider the following code:

+function func() { console.log('!'); }

As you already know, this function is a function expression, regardless of the fact that it has a name (we already found out that the presence of a name is not a criterion at all). Remove this plus - and get Function Declaration:

function func() { console.log('!'); }

Let's put + on the line above before the function - it will again become a Function Expression:

+ function func() { console.log('!'); }

And now after the plus we put the number 1 and a semicolon - our function will become a Function Declaration:

+1; function func() { console.log('!'); }

Why so: because on the first line one complete command is written, closed with a semicolon. Therefore, this command does not affect our function in any way.

In fact, the semicolon can be removed, because in JavaScript it is not required - the function will still remain a Function Declaration:

+1 function func() { console.log('!'); }

But if after 1 you put one more plus, then the function will become a Function Expression:

+1+ function func() { console.log('!'); }

Why so: because on the first line there is an unfinished expression - there is a plus and nothing after it. Therefore, the JavaScript interpreter thinks that this plus refers to the line below, that is, to our function.

If there is a complete expression on the first line, then JavaScript automatically puts a semicolon on it and this expression does not affect our function in any way.

Determine if the presented function is a Function Declaration or a Function Expression:

- function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

-1; function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

-1 function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

1 function func() { console.log('!'); }

Determine if the presented function is a Function Declaration or a Function Expression:

-1- function func() { console.log('!'); }

Expression to the right

Note that the expression in which the function is involved must be to the left of it. If we try to do something to the right of a function, it won't make it a function expression. An example:

function func() { // this is Function Declaration console.log('!'); } + 1;

Why so: because in this case this +1 is just a new command written after the function. If you write this command from a new line, everything becomes clearer:

function func() { console.log('!'); } +1; // just a command

Let's make a Function Expression out of our function. For example, put + in front of the function:

+function func() { // this is Function Expression console.log('!'); } + 1;

Or let's do the assignment:

let test = function func() { // this is Function Expression console.log('!'); } + 1;

Or pass as a parameter to alert:

console.log(function func() { // this is Function Expression console.log('!'); } + 1);

Determine if the presented function is a Function Declaration or a Function Expression:

function func() { console.log('!'); } +1;

Determine if the presented function is a Function Declaration or a Function Expression:

function func() { console.log('!'); } + 1;

Determine if the presented function is a Function Declaration or a Function Expression:

+function func() { console.log('!'); } + 1;

Determine if the presented function is a Function Declaration or a Function Expression:

+ function func() { console.log('!'); } + 1;

Determine if the presented function is a Function Declaration or a Function Expression:

+ 1 function func() { console.log('!'); } + 1;

Determine if the presented function is a Function Declaration or a Function Expression:

function func() { console.log('!'); } + console.log('!');
enru