Functions are one of the most important building blocks of code in JavaScript.

Functions consist of a set of commands and usually perform one specific task (for example, summing numbers, calculating a root, etc.).

Code placed in a function will be executed only after the explicit call to that function.

Function declaration

1.Syntax:

//Function declaration function FunctionName(var1, var2)( Function code ) //Function call FunctionName(var1,var2);

2. Syntax:

//Function declaration var functionname=function(var1, var2)(Function code) //Function call functionname(var1,var2);

function name specifies the name of the function. Each function on the page must have a unique name. The function name must be specified in Latin letters and must not start with numbers.

per1 and per2 are variables or values ​​that can be passed inside a function. An unlimited number of variables can be passed to each function.

Note: even if no variables are passed to the function, don't forget to insert parentheses "()" after the function name.

Note: Function names in JavaScript are case sensitive.

JavaScript function example

The messageWrite() function in the example below will be executed only after the button is clicked.

Note: this example uses the onclick event. JavaScript events will be discussed in detail later in this tutorial.

Passing Variables to Functions

You can pass an unlimited number of variables to functions.

Note: all manipulations on variables inside functions are actually performed not on the variables themselves, but on their copy, so the contents of the variables themselves do not change as a result of the execution of the functions.

/* Define a function that adds 10 to the passed variable and outputs the result to the page */ function plus(a)( a=a+10; document.write("Function output: " + a+"
"); ) var a=25; document.write("Variable value before function call: "+a+"
"); // Call the function passing it the variable a plus(a); document.write("The value of the variable after calling the function: "+a+"
");

Quick View

To access a global variable from a function rather than a copy of it, use window.variable_name.

Function plus(a)( window.a=a+10; ) var a=25; document.write("Variable value before function call: "+a+"
"); plus(a); document.write("Variable value after function call: "+a+"
");

Quick View

return command

With the command return You can return values ​​from functions.

Quick View

Built-in Functions

In addition to user-defined functions in JavaScript, there are also built-in functions.

For example, the built-in function isFinite allows you to check if the passed value is a valid number.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90.33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("This is a string")+"
");

Quick View

Note: full list built-in JavaScript functions you can find in our .

Local and Global Variables

Variables created inside functions are called local variables. You can only access such variables within the functions in which they were defined.

After the execution of the function code, such variables are destroyed. This means that variables with the same name can be defined in different functions.

Variables that are created outside of function code are called global variables such variables can be accessed from anywhere in the code.

If you declare a variable without var inside a function, it also becomes global.

Global variables are only destroyed when the page is closed.

Quick View

Note: when displayed, var2 will be null because func1 operates on the local "version" of var2.

Using Anonymous Functions

Functions that do not contain a name when declared are called anonymous.

Anonymous functions are basically declared not for their subsequent call from the code as ordinary functions, but for passing to other functions as a parameter.

Function arrMap(arr,func)( var res=new Array; for (var i=0;i ");

Quick View

Do it yourself

Exercise 1. Fix the errors in the code below:

Exercise 1

Fix the error in the code.

Task 2.

  1. Reproduce the code of functions 1-3 by examining their behavior when passing different parameters.
  2. Determine the keyword by interacting with the function 4.

Task 2

//Call the first secret function document.write(secfunc1(4,12) + "
"); // Calling the second secret function document.write(secfunc2(100,10) + "
"); //Call the third secret function secfunc3(23,10); document.write("
"); // Calling the fourth secret function secfunc4("n");

Please enable JavaScript to use the Disqus commenting system.

People think that computer science is an art for geniuses. In reality, the opposite is true - just a lot of people doing things that stand on top of each other, as if making up a wall of small pebbles.

Donald Knuth

You have already seen function calls such as alert . Functions are the bread and butter of JavaScript programming. The idea of ​​wrapping a piece of a program and calling it as a variable is very popular. It is a tool for structuring large programs, reducing repetition, assigning names to subroutines, and isolating subroutines from each other.

The most obvious use of functions is to create a new dictionary. Coming up with words for ordinary human prose is a bad form. In a programming language, this is necessary.

The average adult Russian speaker knows about 10,000 words. A rare programming language contains 10,000 built-in commands. And the vocabulary of a programming language is more clearly defined, so it's less flexible than a human one. Therefore, we usually have to add our own words to it in order to avoid unnecessary repetition.

Function definition

A function definition is a normal variable definition, where the value that the variable receives is the function. For example, the following code defines a variable square that refers to a function that calculates the square of a given number:

var square = function(x) ( return x * x; ); console.log(square(12)); // → 144

A function is created by an expression starting with the function keyword. Functions have a set of parameters (in this case, only x) and a body containing the instructions to be executed when the function is called. The body of a function is always enclosed in curly braces, even if it consists of a single statement.

A function may have several parameters, or none at all. In the following example, makeNoise does not have a list of parameters, while power has two:

Var makeNoise = function() ( console.log("Fuck!"); ); makeNoise(); // → Crap! var power = function(base, exponent) ( var result = 1; for (var count = 0; count< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Some functions return a value, like power and square, others don't, like makeNoise, which has only a side effect. The return statement defines the value returned by the function. When program processing reaches this instruction, it immediately exits the function, and returns this value to the place in the code where the function was called from. return without an expression returns undefined .

Parameters and scope

Function parameters are just like variables, but their initial values ​​are set when the function is called, and not in its code.

An important property of functions is that variables created within a function (including parameters) are local within that function. This means that in the power example, the result variable will be created every time the function is called, and these separate incarnations of it are not related to each other in any way.

This locality of variables only applies to parameters and variables created inside functions. Variables set outside of any function are called global variables because they are visible throughout the program. You can also access such variables within a function, unless you have declared a local variable of the same name.

The following code illustrates this. It defines and calls two functions that assign a value to x. The first declares it as local, thereby changing only the local variable. The second one does not declare, so working with x inside the function refers to the global variable x that was set at the beginning of the example.

var x = "outside"; var f1 = function() ( var x = "inside f1"; ); f1(); console log(x); // → outside var f2 = function() ( x = "inside f2"; ); f2(); console log(x); // → inside f2

This behavior helps prevent accidental interaction between functions. If all variables were used anywhere in the program, it would be very difficult to make sure that one variable is not used for different purposes. And if you were to reuse a variable, you'd run into weird effects where third-party code messes with your variable's values. By treating variables local to functions so that they exist only within the function, the language makes it possible to work with functions as if they were separate little universes, which allows you not to worry about the entire code as a whole.

Nested scopes

JavaScript distinguishes not only between global and local variables. Functions can be defined within functions, resulting in several levels of locality.

For example, the following rather meaningless function contains two more inside:

var landscape = function() ( var result = ""; var flat = function(size) ( for (var count = 0; count< size; count++) result += "_"; }; var mountain = function(size) { result += "/"; for (var count = 0; count < size; count++) result += """; result += "\\"; }; flat(3); mountain(4); flat(6); mountain(1); flat(1); return result; }; console.log(landscape()); // → ___/""""\______/"\_

The flat and mountain functions see the result variable because they are inside the function in which it is defined. But they cannot see each other's count variables, because the variables of one function are outside the scope of the other. And the environment outside the landscape function does not see any of the variables defined inside this function.

In short, in each local scope, you can see all the scopes that contain it. The set of variables available inside a function is determined by the place where this function is declared in the program. All variables from the blocks surrounding the function definition are visible - including those defined at the top level in the main program. This approach to scopes is called lexical.

People who have studied other programming languages ​​might think that any block enclosed in curly braces creates its own local environment. But in JavaScript, only functions create scope. You can use standalone blocks:

var something = 1; ( var something = 2; // Do something with variable something... ) // Exit block...

But something inside the block is the same variable as outside. Although such blocks are allowed, it only makes sense to use them for if statements and loops.

If this seems strange to you, it seems so not only to you. JavaScript 1.7 introduced the let keyword, which works like var, but creates variables that are local to any given block, not just the function.

Functions as values

Function names are usually used as a name for a piece of a program. Such a variable is once set and does not change. So it's easy to confuse a function with its name.

But these are two different things. A function call can be used like a simple variable - for example, they can be used in any expression. It is possible to store a function call in a new variable, pass it as a parameter to another function, and so on. Also, the variable that stores the function call remains an ordinary variable and its value can be changed:

Var launchMissiles = function(value) ( ​​missileSystem. launch("please!"); ); if (safeMode) launchMissiles = function(value) (/* release */);

In Chapter 5, we'll discuss the wonderful things that can be done by passing function calls to other functions.

Function declaration

There is a shorter version of the expression “var square = function…”. The function keyword can be used at the beginning of a statement:

function square(x) ( return x * x; )

This is a function declaration. The statement defines the variable square and assigns the given function to it. So far everything is ok. There is only one pitfall in such a definition.

Console.log("The future says:", future()); function future() ( return "We STILL have no flying cars."; )

This code works even though the function is declared below the code that uses it. This is because function declarations are not part of the normal top-down execution of programs. They "move" to the top of their scope and can be called by any code in that scope. This is sometimes convenient because you can write the code in the order that makes the most sense without having to worry about having to define all the functions above where they are used.

But what happens if we place a function declaration inside a conditional block or loop? You don't have to do that. Historically, different platforms for running JavaScript handled such cases differently, and the current language standard forbids doing so. If you want your programs to run consistently, use function declarations only inside other functions or the main program.

Function example() ( function a() () // Normule if (something) ( function b() () // Ay-yy-yy! ) )

call stack
It's helpful to take a closer look at how execution order works with functions. Here is a simple program with a few function calls:

Function greet(who) ( console.log("Hi, " + who); ) greet("Semyon"); console.log("Pokeda");

It is processed something like this: calling greet causes the pass to jump to the beginning of the function. It calls the built-in console.log function, which takes control, does its thing, and returns control. Then it reaches the end of the greet, and returns to the place from which it was called. The next line calls console.log again.

Schematically, this can be shown as follows:

Top greet console.log greet top console.log top

Because the function must return to where it was called from, the computer must remember the context from which the function was called. In one case, console.log should change back to greet. In another, it returns to the end of the program.

The place where the computer remembers the context is called the stack. Each time the function is called, the current context is pushed on top of the stack. When the function returns, it pops the top context from the stack and uses it to keep going.

Stack storage requires memory space. When the stack grows too big, the computer stops executing and issues something like “stack overflow” or “too much recursion”. The following code demonstrates this - it asks the computer a very complex question that leads to endless jumps between two functions. More precisely, it would be infinite jumps if the computer had an infinite stack. In reality, the stack overflows.

Function chicken() ( return egg(); ) function egg() ( return chicken(); ) console.log(chicken() + " came first."); // → ??

Optional Arguments
The following code is completely legal and runs without problems:

Alert("Hello", "Good evening", "Hello everyone!");

Officially, the function takes one argument. However, when challenged like this, she does not complain. It ignores the rest of the arguments and shows "Hello".

JavaScript is very lenient about the number of arguments passed to a function. If you pass too much, the extra ones will be ignored. Too few - missing ones will be assigned the value undefined.

The disadvantage of this approach is that it is possible - and even likely - to pass the wrong number of arguments to the function, and no one will complain to you about this.

The upside is that you can create functions that take optional arguments. For example, in the next version of the power function, it can be called with both two and one argument - in the latter case, the exponent will be equal to two, and the function works like a square.

Function power(base, exponent) ( if (exponent == undefined) exponent = 2; var result = 1; for (var count = 0; count< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

In the next chapter, we'll see how the body of a function can tell you the exact number of arguments passed to it. This is useful because allows you to create a function that takes any number of arguments. For example, console.log uses this property and prints out all the arguments passed to it:

Console.log("R", 2, "D", 2); // → R 2 D 2

Closures

The ability to use function calls as variables, coupled with the fact that local variables are re-created every time a function is called, brings us to an interesting point. What happens to local variables when a function fails?

The following example illustrates this issue. It declares the wrapValue function, which creates a local variable. It then returns a function that reads that local variable and returns its value.

Function wrapValue(n) ( var localVariable = n; return function() ( return localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue(2); console log(wrap1()); // → 1 console.log(wrap2()); // → 2

This is valid and works as it should - access to the variable remains. Moreover, multiple instances of the same variable can exist at the same time, further confirming the fact that local variables are re-created with each function call.

This ability to work with a reference to some instance of a local variable is called a closure. A function that closes local variables is called a closing function. Not only does it free you from worrying about variable lifetimes, it also allows you to use functions creatively.

With a slight change, we turn our example into a function that multiplies numbers by any given number.

Function multiplier(factor) ( return function(number) ( return number * factor; ); ) var twice = multiplier(2); console.log(twice(5)); // → 10

A separate variable like localVariable from the wrapValue example is no longer needed. Since the parameter is itself a local variable.

It takes practice to start thinking like this. A good version of the mental model is to imagine that the function freezes the code in its body and wraps it in a package. When you see return function(...) (...), think of it as a control panel for a piece of code frozen for use later.

In our example, the multiplier returns a frozen piece of code that we store in the twice variable. The last line calls the function contained in the variable, which activates the saved code (return number * factor;). It still has access to the factor variable that was defined when the multiplier was called, and it also has access to the argument passed during unfreeze (5) as a numeric parameter.

recursion

A function may well call itself if it takes care not to overflow the stack. Such a function is called recursive. Here is an example of an alternative implementation of exponentiation:

Function power(base, exponent) ( if (exponent == 0) return 1; else return base * power(base, exponent - 1); ) console.log(power(2, 3)); // → 8

This is how mathematicians define exponentiation, and perhaps this describes the concept more elegantly than a cycle. The function calls itself many times with different arguments to achieve multiple multiplication.

However, this implementation has a problem - in a normal JavaScript environment, it is 10 times slower than the version with a loop. Looping is cheaper than calling a function.

The speed versus elegance dilemma is quite interesting. There is a certain gap between human convenience and machine convenience. Any program can be sped up by making it bigger and more intricate. The programmer is required to find the right balance.

In the case of first exponentiation, the inelegant loop is quite simple and straightforward. It doesn't make sense to replace it with recursion. Often, however, programs work with such complex concepts that one wants to reduce efficiency by increasing readability.

The basic rule, which has been repeated many times, and with which I completely agree - do not worry about performance until you are sure that the program is slowing down. If so, find the parts that last the longest and trade elegance for efficiency there.

Of course, we shouldn't completely ignore performance right away. In many cases, as with exponentiation, we do not get much simplicity from elegant solutions. Sometimes an experienced programmer sees right away that a simple approach will never be fast enough.

I bring this up because too many novice programmers cling to efficiency even in small things. The result is larger, more complex, and often not without errors. Such programs take longer to write, and they often work not much faster.

But recursion isn't always just a less efficient alternative to loops. Some problems are easier to solve with recursion. Most often, this is a traversal of several tree branches, each of which can branch.

Here's a riddle for you: you can get an infinite number of numbers, starting with the number 1, and then either adding 5 or multiplying by 3. How do we write a function that, given a number, tries to find a sequence of such additions and multiplications that lead to a given number? For example, the number 13 can be obtained by first multiplying 1 by 3 and then adding 5 twice. And the number 15 is generally impossible to get like that.

Recursive solution:

Function findSolution(target) ( function find(start, history) ( if (start == target) return history; else if (start > target) return null; else return find(start + 5, "(" + history + " + 5)") || find(start * 3, "(" + history + " * 3)"); ) return find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

This example does not necessarily find the shortest solution - it satisfies any. I do not expect you to immediately understand how the program works. But let's get to the bottom of this great exercise in recursive thinking.

The internal function find is recursive. It takes two arguments - the current number and a string that contains a record of how we arrived at that number. And returns either a string showing our sequence of steps, or null.

To do this, the function performs one of three actions. If the given number is equal to the goal, then the current history is just the way to achieve it, which is why it is returned. If the given number more purpose, it makes no sense to continue multiplying and adding, because this way it will only increase. And if we haven't reached the goal yet, the function tries both possible paths starting from the given number. She summons herself twice, once with each of the ways. If the first call returns not null, it returns. Otherwise, the second one is returned.

To better understand how the function achieves the desired effect, let's look at its calls that occur in search of a solution for the number 13.

Find(1, "1") find(6, "(1 + 5)") find(11, "((1 + 5) + 5)") find(16, "(((1 + 5) + 5 ) + 5)") too big find(33, "(((1 + 5) + 5) * 3)") too big find(18, "((1 + 5) * 3)") too big find( 3, "(1 * 3)") find(8, "((1 * 3) + 5)") find(13, "(((1 * 3) + 5) + 5)") found!

The indentation shows the depth of the call stack. The first time the find function calls itself twice to check the solutions starting with (1 + 5) and (1 * 3). The first call looks for a solution starting with (1 + 5) and uses recursion to check all solutions that yield a number less than or equal to the desired number. Doesn't find it and returns null. Then the operator || and jumps to a function call that examines the option (1 * 3). Here we are lucky, because in the third recursive call we get 13. This call returns a string, and each of the || passes this string above along the way, returning the solution as a result.

Grow Functions

There are two more or less natural ways to introduce functions into a program.

First, you write similar code multiple times. This should be avoided - more code means more room for errors and more reading material for those trying to understand the program. So we take a recurring functionality, match it good name and put it in a function.

The second way is that you discover a need for some new functionality that is worthy of being placed in a separate function. You start with the name of the function, and then write its body. You can even start by writing the code that uses the function before the function itself is defined.

How difficult it is for you to name a function shows how well you understand its functionality. Let's take an example. We need to write a program that prints two numbers, the number of cows and chickens on the farm, followed by the words "cows" and "chickens". You need to add zeros to the numbers in front so that each occupies exactly three positions.

007 Cows 011 Hens

Obviously, we need a function with two arguments. Let's start coding.
// printFarmInventory function printFarmInventory(cows, chickens) ( var cowString = String(cows); while (cowString.length< 3) cowString = "0" + cowString; console.log(cowString + " Коров"); var chickenString = String(chickens); while (chickenString.length < 3) chickenString = "0" + chickenString; console.log(chickenString + " Куриц"); } printFarmInventory(7, 11);

If we add .length to a string, we get its length. It turns out that the while loops add leading zeros to the numbers until they get a string of 3 characters.

Ready! But as soon as we are about to send the code to the farmer (along with a hefty check, of course), he calls and tells us that he has got pigs on the farm, and could we add the output of the number of pigs to the program?

Of course it is possible. But when we start copying and pasting the code from these four lines, we realize that we need to stop and think. There must be a better way. We are trying to improve the program:

// outputZeroPaddedWithLabel function printZeroPaddedWithLabel(number, label) ( var numberString = String(number); while (numberString.length< 3) numberString = "0" + numberString; console.log(numberString + " " + label); } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { printZeroPaddedWithLabel(cows, "Коров"); printZeroPaddedWithLabel(chickens, "Куриц"); printZeroPaddedWithLabel(pigs, "Свиней"); } printFarmInventory(7, 11, 3);

Works! But the name printZeroPaddedWithLabel is a little strange. It combines three things - output, zero padding, and a label - into one function. Instead of stuffing the entire repeating fragment into a function, let's highlight one concept:

// add Zeros function zeroPad(number, width) ( var string = String(number); while (string.length< width) string = "0" + string; return string; } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { console.log(zeroPad(cows, 3) + " Коров"); console.log(zeroPad(chickens, 3) + " Куриц"); console.log(zeroPad(pigs, 3) + " Свиней"); } printFarmInventory(7, 16, 3);

A function with a nice, descriptive name zeroPad makes the code easier to understand. And it can be used in many situations, not only in our case. For example, to display formatted tables with numbers.

How smart and versatile should functions be? We can write like the simplest function, which pads a number with zeros up to three positions, and a fancy general-purpose number formatting function that supports fractions, negative numbers, dot alignment, complement different characters, etc.

A good rule of thumb is to add only the functionality that you definitely need. Sometimes it's tempting to create general purpose frameworks for every little need. Resist him. You will never finish the job, but just write a bunch of code that no one will use.

Functions and Side Effects

Functions can be roughly divided into those that are called because of their side effects and those that are called to get some value. Of course, it is also possible to combine these properties in one function.

The first helper function in the farm example, printZeroPaddedWithLabel, is called because of the side effect of printing a string. The second, zeroPad, because of the return value. And it's no coincidence that the second feature comes in handy more often than the first. Functions that return values ​​are easier to combine with each other than functions that create side effects.

A pure function is a special kind of value-returning function that not only has no side effects, but also does not depend on the side effects of the rest of the code - for example, does not work with global variables that can be accidentally changed somewhere else. A pure function, when called with the same arguments, returns the same result (and does nothing else) - which is pretty nice. It's easy to work with her. The call of such a function can be mentally replaced by the result of its work, without changing the meaning of the code. When you want to test such a function, you can simply call it and be sure that if it works in this context, it will work in any. Not so pure functions can return different results depending on many factors, and have side effects that are difficult to test and account for.

However, do not be shy to write functions that are not quite clean, or start a sacred cleansing of the code from such functions. Side effects are often helpful. There is no way to write clean version console.log function, and this function is quite useful. Some operations are easier to express using side effects.

Outcome

This chapter showed you how to write your own functions. When the function keyword is used as an expression, returns a pointer to the function call. When used as a statement, you can declare a variable by assigning a function call to it.

The key to understanding functions is local scopes. Parameters and variables declared inside a function are local to it, recreated each time it is called, and are not visible from outside. Functions declared inside another function have access to its scope.

It is very useful to divide the different tasks performed by the program into functions. You don't have to repeat yourself, functions make code more readable by separating it into semantic parts, in the same way that chapters and sections of a book help organize plain text.

Exercises

Minimum
In the previous chapter, the Math.min function was mentioned, which returns the smallest of its arguments. Now we can write such a function ourselves. Write a min function that takes two arguments and returns the minimum of them.

Console.log(min(0, 10)); // → 0 console.log(min(0, -10)); // → -10

recursion
We have seen that the % (remainder) operator can be used to determine if a number is even (% 2). Here is another way to determine:

Zero is even.
The unit is odd.
Any number N has the same parity as N-2.

Write a recursive isEven function according to these rules. It must take a number and return a boolean value.

Test it on 50 and 75. Try giving it -1. Why is she behaving this way? Is it possible to fix it somehow?

Test it on 50 and 75. See how it behaves on -1. Why? Can you think of a way to fix this?

Console.log(isEven(50)); // → true console.log(isEven(75)); // → false console.log(isEven(-1)); // → ??

We count beans.

The character number N of a string can be obtained by adding .charAt(N)("string".charAt(5)) to it, in a similar way to getting the length of a string with .length. The return value will be a single character string (for example, "k"). The first character of the string has position 0, which means that the last character will have position string.length - 1. In other words, a string of two characters has length 2, and its character positions will be 0 and 1.

Write a countBs function that takes a string as an argument and returns the number of "B" characters in the string.

Then write a countChar function that works a lot like countBs, except it takes a second parameter, the character we'll be looking for in the string (instead of just counting the number of "B" characters). To do this, rewrite the countBs function.

Jump statements and exception handling

Another category of JavaScript language operators are jump operators. As the name suggests, these statements cause the JavaScript interpreter to jump to a different location in the program code. The break statement causes the interpreter to jump to the end of a loop or other statement. The continue statement causes the interpreter to skip the rest of the loop body, jump back to the beginning of the loop, and start a new iteration. AT JavaScript it is possible to label statements with names, so that break and continue statements can be explicitly indicated to which loop or to which other statement they belong.

The return statement causes the interpreter to jump from the called function back to the point at which it was called and return the value of the call. The throw statement throws an exception and is designed to work in conjunction with the try/catch/finally statements that define the block. program code to handle the exception. This is a rather complicated kind of jump statements: when an exception occurs, the interpreter jumps to the nearest enclosing exception handler, which may be in the same function or higher, on the return stack of the called function.

Each of these jump operators is described in more detail in the following subsections.

Instruction Labels

Any statement can be marked with an identifier and a colon before it:

identifier: instruction

When you tag an instruction, you give it a name that can then be used as a reference anywhere in the program. You can mark any instruction, but it only makes sense to mark instructions that have a body, such as loops and conditional statements.

By giving a name to the loop, it can then be used in break and continue statements, inside the loop to exit from it, or to jump to the beginning of the loop, to the next iteration. The break and continue statements are the only statements in the JavaScript language that can contain labels—they are discussed in more detail later. The following is an example of a while statement with a label and a continue statement using that label:

Mainloop: while (token != null) ( // Program code omitted... continue mainloop; // Go to the next iteration of the named loop )

The identifier used as the statement label can be any valid JavaScript identifier except reserved word. Label names are separate from variable and function names, so you can use identifiers that match variable or function names as labels.

Instruction labels are defined only within the instructions to which they apply (and, of course, within the instructions nested within them). Nested instructions cannot be labeled with the same identifiers as their containing instructions, but two independent instructions can be labeled with the same label. Labeled instructions can be re-tagged. That is, any instruction can have multiple labels.

break statement

The break statement causes the innermost loop or switch statement to exit immediately. We have already seen examples of using a break statement inside a switch statement earlier. In loops, it is usually used to immediately exit the loop when, for some reason, it is necessary to terminate the execution of the loop.

When the cycle is very complex condition completion, it is often easier to implement these conditions with a break statement than to try to express them in a single loop conditional. The following example tries to find an array element with a specific value. The loop ends in the usual way when the end of the array is reached, or with the break statement, as soon as the desired value is found:

Var arr = ["a","b","c","d","e"], result; for (var i = 0; i

In JavaScript, it is allowed to specify the label name after keyword break (identifier without colon):

break label_name;

When the break statement is used with a label, it jumps to the end of the named statement or terminates its execution. In the absence of an instruction with the specified label, an attempt to use this form of the break statement generates a syntax error. A named statement does not have to be a loop or a switch statement. The labeled break statement can "escape" from any containing statement. The enclosing instruction may even be simple block instructions enclosed in curly braces for the sole purpose of marking it.

A newline character cannot be inserted between the break keyword and the label name. This is because the JavaScript interpreter automatically inserts missing semicolons: if you break a line of code between the break keyword and the label that follows it, the interpreter will assume that you meant the simple form of this operator without a label, and add a semicolon.

The labeled break statement is required only when you want to break the execution of a statement that is not the nearest enclosing loop or switch statement.

continue statement

The continue statement is similar to the break statement. However, instead of exiting the loop, the continue statement starts a new iteration of the loop. The syntax for the continue statement is as simple as the syntax for the break statement. The continue statement can also be used with a label.

The continue statement, whether unlabeled or labeled, can only be used within the body of a loop. Using it anywhere else results in a syntax error. When a continue statement is executed, the current iteration of the loop is interrupted and the next one begins. For different types cycles means different things:

    In the while loop, the expression specified at the beginning of the loop is checked again, and if it is true, the body of the loop is executed from the beginning.

    The do/while loop jumps to the end of the loop, where the condition is checked again before the loop is repeated.

    In the for loop, the increment expression is evaluated and the test expression is evaluated again to determine whether the next iteration should be performed.

    In the for/in loop, the loop starts anew with the assignment of the specified name variable next property.

Note the difference in the behavior of the continue statement in while and for loops. The while loop returns directly to its condition, and for loop first evaluates the increment expression and then returns to the condition. The following example shows the use of an unlabeled continue statement to exit the current iteration of a loop for even numbers:

var sum = 0; // Calculate the sum of odd numbers from 0 - 10 for (var i = 0; i

The continue statement, like break, can be used in nested loops in a form that includes a label, in which case the loop restarted is not necessarily the one immediately containing the continue statement. Also, as with break, newlines between the continue keyword and the label name are not allowed.

return statement

A function call is an expression, and like all expressions, it has a value. The return statement inside functions is used to determine the value returned by the function. The return statement can only be placed in the body of a function. Its presence anywhere else is a syntax error. When a return statement is executed, the function returns the value of the expression to the calling program. For example:

If a function does not have a return statement, when it is called, the interpreter will execute the instructions in the function body one by one until it reaches the end of the function, and then return control to the program that called it. In this case, the call expression will return undefined. The return statement is often the last statement in a function, but this is completely optional: the function will return control to the calling program as soon as the return statement is reached, even if it is followed by other statements in the function body.

The return statement can also be used without an expression, in which case it simply aborts the function and returns undefined to the caller. For example:

Function myFun(arr) ( // If the array contains negative numbers, abort the function for (var i = 0; i

throw statement

Exception is a signal indicating the occurrence of some kind of exception or error. Raising an exception (throw) is a way to signal such an error or exception. To catch an exception (catch) means to handle it, i.e. take action necessary or appropriate to recover from the exception.

In JavaScript, exceptions are thrown when a run-time error occurs and when the program explicitly raises it with the throw statement. Exceptions are caught using try/catch/finally statements, which are described later.

The throw statement has the following syntax:

throw expression;

The result of an expression can be a value of any type. The throw statement can be passed a number representing the error code, or a string containing the text of the error message. JavaScript interpreter throws exceptions using an instance of a class error one of its subclasses, and you can also use a similar approach. The Error object has a property name, which defines the error type, and the property message A containing the string passed to the constructor function. The following is an example of a function that raises an Error object when called with an invalid argument:

// The factorial function of a number function factorial(number) ( // If the input argument is not valid value, // an exception is thrown! if (number 1; i *= number, number--); /* empty loop body */ return i; ) console. log("5! = ", factorial(5)); console. log("-3! = ", factorial(-3));

When an exception is thrown, the JavaScript interpreter immediately aborts normal program execution and jumps to the nearest exception handler. Exception handlers use the catch statement of the try/catch/finally construct, which is described in the next section.

If the block of code in which the exception was thrown does not have a corresponding catch construct, the interpreter parses the following outdoor unit program code and checks if an exception handler is associated with it. This continues until the handler is found.

If an exception is thrown in a function that does not contain a try/catch/finally construct to handle it, then the exception propagates up into the code that called the function. This way exceptions propagate along the lexical structure JavaScript methods up the call stack. If an exception handler is never found, the exception is treated as an error and reported to the user.

try/catch/finally construct

The try/catch/finally construct implements JavaScript's exception handling mechanism. try statement in this construct simply defines a block of code in which exceptions are handled. The try block is followed by catch statement with a block of statements to be called if an exception occurs anywhere in the try block. The catch statement is followed by a block finally A that contains code that performs the final operations and is guaranteed to run regardless of what happens in the try block.

Both the catch block and the finally block are optional, but at least one of them must be present after the try block. try, catch and finally blocks start and end curly braces. This is a mandatory part of the syntax and cannot be omitted even if there is only one statement between them.

The following snippet illustrates the syntax and purpose of the try/catch/finally construct:

Try ( // Normally, this code will run smoothly from start to finish. // But at some point, an exception may // be thrown in it, either directly with the throw statement, or indirectly, // by calling the method that throws the exception. ) catch (ex) ( // The statements in this block are executed if and only if an exception occurs in the try block //. These statements can use a local variable ex that // refers to the Error object or to another value specified in the throw statement. // This block can either handle the exception in some way, either // ignore it and do something else, or // rethrow the exception with a throw statement. ) finally ( // This block contains statements that are always executed, regardless of whether , // what happened in the try block They are executed if the try block has ended: // 1) as usual, reaching the end of the block // 2) due to break, continue or return statements // 3) with an exception handled by in the catch block above // ​​4) with an uncaught exception that continues // to propagate to higher levels)

Note that the catch keyword is followed by an identifier in parentheses. This identifier is similar to a function parameter. When an exception is caught, this parameter will be set to an exception (for example, an Error object). Unlike a normal variable, the identifier associated with a catch statement exists only in the body of the catch block.

The following is a more realistic example of a try/catch construct. It calls the factorial() method defined in the previous example, and prompt methods() and alert() client-side JavaScript to organize input and output:

Try ( // Ask the user for a number var n = Number(prompt("Enter a positive number", "")); // Calculate the factorial of a number, assuming // the input is valid var f = factorial(n); // Print the result alert(n + "! = " + f); ) catch (ex) ( // If the data is incorrect, control will be transferred here alert(ex); // Notify the user about the error )

If the user enters a negative number, a warning message will be displayed:

This is an example of a try/catch construct without a finally statement. Although finally is not used as often as catch, it is nevertheless sometimes useful. The finally block is guaranteed to execute if at least some part of the try block has executed, regardless of how the code in the try block ended. This feature is typically used to perform final operations after code has been executed in a try continuation.

In a normal situation, control reaches the end of the try block and then jumps to the finally block, which performs the necessary final operations. If control exits a try block as a result of a return, continue, or break statement, the finally block is executed before control is transferred elsewhere.

If an exception occurs in a try block and there is an appropriate catch block to handle it, control is first transferred to the catch block and then to the finally block. If there is no local catch block, then control first passes to the finally block and then jumps to the nearest outer catch block that can handle the exception.

If the finally block itself transfers control with a return, continue, break, or throw statement or by calling a method that throws an exception, the pending transfer is canceled and a new one is executed. For example, if the finally block throws an exception, that exception will replace any previously thrown exception.

Operator return terminates the current function and returns its value.

The source code for this interactive example is stored in a GitHub repository. If you want to participate in the project interactive examples please clone https://github.com/mdn/interactive-examples

Syntax

return [[expression]]; expression The expression whose value will be returned. If not specified, undefined is returned instead.

Description

When a return statement is called in a function, its execution stops. The specified value is returned to the place where the function was called. For example, the following function returns the squared value of its argument, x (where x is a number):

function square(x) ( return x * x; ) var demo = square(3); // demo value will be 9

If no return value is specified, undefined is returned instead.

The following expressions always terminate the execution of a function:

return; return true; return false; return x; return x + y / 3;

Automatic semicolons

function magic(x) ( return function calc(x) ( return x * 42 ); ) var answer = magic(); answer(1337); // 56154

Specifications

Specification Status Comment
ECMAScript 1st Edition (ECMA-262) Standard original definition
ECMAScript 5.1 (ECMA-262)
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
Definition of "Return statement" in this specification.
Standard
ECMAScript Latest Draft (ECMA-262)
Definition of "Return statement" in this specification.
Draft

Browser Compatibility

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check it out from the https://github.com/mdn/browser-compat-data repository and send us a pull request for your changes.

Update compatibility data on GitHub

ComputersMobileserver
ChromeedgeFirefoxInternet ExplorerOperasafariandroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
returnChrome Full Support 1 edge Full Support 12 Firefox Full Support 1 IE Full Support 3 Opera Full Support Yessafari Full Support Yeswebview android Full Support 1 Chrome Android Full Support 18 Firefox Android Full Support 4 OperaAndroid Full Support YesSafari iOS Full Support YesSamsung Internet Android Full Support 1.0 nodejs Full Support Yes