Functional expression

In JavaScript, a function is not a “magic language construct”, but a special kind of value.

The syntax we used in the previous section is called function declarations:

function sayHi() {
  alert( "Hello" );
}
Copy the code

Another syntax for creating functions is called function expressions.

It is usually written like this:

let sayHi = function() {
  alert( "Hello" );
};
Copy the code

Here, the function is created and explicitly assigned to a variable, just like any other assignment. No matter how a function is defined, it is just a value stored in the variable sayHi.

The above two examples of code mean the same thing: “Create a function and store it in the variable sayHi”.

We can also print the value of this variable with alert:

function sayHi() {
  alert( "Hello" );
}

alert( sayHi ); // Display the function code
Copy the code

Notice that the last line of code does not run the function because there are no parentheses after sayHi. In other programming languages, the mere mention of a function’s name causes the function call to execute, but this is not the case in JavaScript.

In JavaScript, a function is a value, so we can treat it as a value. The above code shows a string value, the source code for the function.

Indeed, a function is a special value in the sense that we can call it like sayHi().

But it is still a value, so we can use it just like any other type of value.

We can copy functions to other variables:

function sayHi() {   / / (1) to create
  alert( "Hello" );
}

let func = sayHi;    / / (2) copy

func(); // Hello // (3) Run the copied value (fine)!
sayHi(); // Hello // works here too (why not)
Copy the code

Explain in detail what happened in the previous code:

  1. (1)The line declaration creates the function and puts it into the variablesayHi.
  2. (2)linesayHiCopy to variablefunc. Please note:sayHiThere are no parentheses behind it. If I have parentheses,func = sayHi()thesayHi()Write the result of the call tofuncRather thansayHi functionItself.
  3. Now the function can passsayHi()func()There are two ways to call.

Note that we can also declare sayHi in the first line using a function expression:

let sayHi = function() {
  alert( "Hello" );
};

let func = sayHi;
// ...
Copy the code

The declared functions are the same.


Why is there a semicolon at the end here?

You might wonder why the function expression ends with a semicolon; Function declarations do not:

function sayHi() {
  // ...
}

let sayHi = function() {
  // ...
};
Copy the code

The answer is simple:

  • You don’t need a semicolon at the end of a code block;, likeif { ... }.for { }.function f { }You don’t have to add it.
  • Function expressions are inside statements:let sayHi = ... ;, as a value. It is not a code block but an assignment statement. Is it recommended to add a semicolon at the end of the statement, regardless of the value;. So the semicolon here has nothing to do with the function expression itself, it’s just used to terminate the statement.

The callback function

Let’s take a few more examples of how functions can be passed as values and how function expressions can be used.

Let’s write a function ask(question, yes, no) with three arguments:

Question: The text of a question

Yes: Script to run when the answer is “yes”

No: Script to run when the answer is “no”

The function needs to ask a question and, depending on the user’s answer, call yes() or no() :

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

function showOk() {
  alert( "You agreed." );
}

function showCancel() {
  alert( "You canceled the execution." );
}

// Usage: the functions showOk and showCancel are passed to ask as arguments
ask("Do you agree?", showOk, showCancel);
Copy the code

In practice, such functions are very useful. The biggest difference between the actual development and the example above is that the functions in the actual development interact with users in a more complex way than simple confirmations. In a browser, such a function usually draws a nice question window. But that’s a story for another day.

Ask’s two Arguments objects, showOk and showCancel, can be called callback functions or simply callbacks.

The main idea is that we pass a function and expect it to be “called back” later if necessary. In our example, showOk is the callback that answers “yes” and showCancel is the callback that answers “no”.

We can use function expressions to greatly abbreviate the same function:

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  "Do you agree?".function() { alert("You agreed."); },
  function() { alert("You canceled the execution."); });Copy the code

Here directly in the ask(…) Function declaration inside the call. These two functions have no names, so they are called anonymous functions. Such functions are not accessible outside of Ask (because no variables are assigned to them), but that’s exactly what we want.

Such code is very common in our scripts, which is consistent with the idea of the JavaScript language.


A function is a value that represents an action

Regular values such as strings or numbers represent data.

A function can be thought of as an action.

We can pass them between variables and run them as needed.


Function expressions vs function declarations

Let’s summarize the main differences between function declarations and function expressions.

The first is the syntax: how they are distinguished by code.

  • Function declaration: A function declared as a separate statement in the main code flow.

    // Function declaration
    function sum(a, b) {
      return a + b;
    }
    Copy the code
  • Function expression: A function created in an expression or in another syntactic structure. The following function is created to the right of the assignment expression = :

    // Function expression
    let sum = function(a, b) {
      return a + b;
    };
    Copy the code

A more subtle difference is when the JavaScript engine creates the function.

Function expressions are created when code execution arrives and are only available from that moment.

Let sum = function… At this point, the function is created and can be used from now on (assign, call, etc.).

Function declarations are different.

A function declaration can be called before it is defined.

For example, a global function declaration is visible to the entire script, no matter where it is written in the script.

That’s where the internal algorithm comes in. When JavaScript is ready to run a script, it first looks for global function declarations in the script and creates those functions. We can think of this as the “initialization phase.”

The code is not executed until all function declarations have been processed. So the runtime can use these functions.

For example, the following code will work:

sayHi("John"); // Hello, John

function sayHi(name) {
  alert( `Hello, ${name}` );
}
Copy the code

The function declaration sayHi is created when JavaScript is ready to run the script and is visible anywhere in the script.

… If it were a function expression, it would not work:

sayHi("John"); // error!

let sayHi = function(name) {  // (*) no magic any more
  alert( `Hello, ${name}` );
};
Copy the code

The function expression is created only when the code executes to it. This will only happen in (*) rows. It’s too late.

Another special feature of function declarations is their block-level scope.

In strict mode, when a function is declared within a code block, it is visible anywhere within that code block. It is not visible outside the code block.

For example, imagine that we need to declare a function welcome() depending on the variable age obtained during code execution. And we plan to use it at some point.

If we use function declarations, the following code does not work as expected:

let age = prompt("What is your age?".18);

// Declare a function conditionally
if (age < 18) {

  function welcome() {
    alert("Hello!"); }}else {

  function welcome() {
    alert("Greetings!"); }}/ /... Later use
welcome(); // Error: welcome is not defined
Copy the code

This is because the function declaration is only visible in the block of code in which it resides.

Here’s another example:

let age = 16; // Take 16 as an example

if (age < 18) {
  welcome();               // \ (run)
                           // |
  function welcome() {     // |
    alert("Hello!");       / / | function declarations in a statement it are available at any location in the code block
  }                        // |
                           // |
  welcome();               // / (run)

} else {

  function welcome() {
    alert("Greetings!"); }}// In this case, we call functions outside the curly braces. We cannot see the function declarations inside them.


welcome(); // Error: welcome is not defined
Copy the code

How can we make Welcome visible outside of if?

The correct way to do this is to use a function expression and assign welcome to a variable declared outside of if with proper visibility.

The following code works as desired:

let age = prompt("What is your age?".18);

let welcome;

if (age < 18) {

  welcome = function() {
    alert("Hello!");
  };

} else {

  welcome = function() {
    alert("Greetings!");
  };

}

welcome(); // Now it's ok
Copy the code

Or we could use the question mark operator? To further simplify the code:

let age = prompt("What is your age?".18);

let welcome = (age < 18)?function() { alert("Hello!"); } :
  function() { alert("Greetings!"); };

welcome(); // Now it's ok
Copy the code

When to choose between function declarations and function expressions?

As a rule of thumb, when we need to declare a function, we first consider the function declaration syntax. It provides more flexibility for organizing code. Because we can call these functions before we declare them.

This also makes the code more readable, because it looks for function f(…) in the code. {… } let f = function(…) {… } is easier. Function declarations are more “eye-catching”.

… However, if for some reason function declarations are not for us (we just looked at the example above), then function expressions should be used.


conclusion

  • Functions are values. They can be assigned, copied, or declared anywhere in the code.
  • If a function is declared as a separate statement in the main code flow, it is called a “function declaration.”
  • If the function is created as part of an expression, it is called a “function expression.”
  • The internal algorithm handles function declarations before executing code blocks. So function declarations are visible anywhere within the block of code in which they are declared.
  • Function expressions are created when the execution process arrives.

In most cases, when we need to declare a function, it is best to use a function declaration because the function is visible before it is declared. This gives us more flexibility in how our code is organized and generally makes our code more readable.

Therefore, function expressions should be used only when the function declaration is inappropriate for the corresponding task. We’ve seen several examples in this chapter, and we’ll see more.

This article was first published on the wechat public account “Technology Talk”, welcome to follow.


Modern JavaScript Tutorials: Open source modern JavaScript tutorials from beginner to advanced quality. React provides a JavaScript tutorial for MDN learners.

Read for free online: zh.javascript.info


Scan the QR code below and follow the wechat public account “Technology Chat” to subscribe for more exciting content.