23.07.2020

JavaScript functions. Expressive JavaScript: Functions Local and Global Variables


Operator return ends the execution of the current function and returns its value.

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

Syntax

return [[expression]]; expression An expression to return a value. If not specified, undefined is returned instead.

Description

When a return statement is called in a function, its execution is terminated. Specified value returns 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 interrupt the execution of a function:

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

Automatic semicoloning

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

Specifications (edit)

Specification Status A comment
ECMAScript 1st Edition (ECMA-262) Standard Initial definition
ECMAScript 5.1 (ECMA-262)
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of "Return statement" in this specification.
Standard
ECMAScript Latest Draft (ECMA-262)
The 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 get it from the repository https://github.com/mdn/browser-compat-data and send us a pull request to pull 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 Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support 1.0 nodejs Full support Yes

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

Donald Knuth

You've already seen calls to functions such as alert. Functions are the bread and butter of JavaScript programming. The idea of ​​wrapping a piece of program and calling it as a variable is in great demand. It is a tool for structuring large programs, reducing repetition, naming 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 bad form. In a programming language, this is necessary.

The average Russian-speaking adult 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 is less flexible than a human one. Therefore, we usually have to add our own words to it to avoid unnecessary repetition.

Function definition

A function definition is a normal variable definition, where the value that the variable receives is a 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, just x), and a body that contains 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 can 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 ("Waggle!");); makeNoise (); // → Chryp! 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 do not, like makeNoise, which only produces a side effect. The return statement defines the return value of the function. When program processing reaches this instruction, it immediately exits the function, and returns this value to the point in the code from where the function was called. return without expression returns undefined.

Parameters and scope

Function parameters are the same 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 example with power, 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 within functions. Variables defined outside of any function are called global because they are visible throughout the entire program. You can also access such variables inside a function, unless you have declared a local variable with the same name.

The following code illustrates this. It defines and calls two functions that assign a value to the variable x. The first declares it as local, thereby changing only the local variable. The second one does not declare, so working with x inside a function refers to the global variable x specified 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 communication 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 the variable, you would run into strange effects when third-party code corrupts the values ​​of your variable. By treating variables local to functions so that they exist only inside a function, the language makes it possible to work with functions as if with separate small universes, which allows you not to worry about the entire code.

Nested scopes

JavaScript distinguishes not only between global and local variables. Functions can be defined within functions, resulting in multiple 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 out of scope for 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 the function is described 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 scoping approach 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 free-standing units:

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

But something inside a block is the same variable as outside. While 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 a function.

Functions as values

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

But these are two different things. Function calls 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 storing the function call remains an ordinary variable and its value can be changed:

Var launchMissiles = function (value) (missileSystem.launch ("or!");); 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 specified function to it. So far, everything is ok. There is only one pitfall in this definition.

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

This code works, although 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 code in the order that makes the most sense without worrying about having to define all functions above where they are used.

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

Function example () (function a () () // Normal if (something) (function b () () // Ay-yay-yay!))

Call stack
It's helpful to take a closer look at how the order of execution works with functions. Here simple program with multiple function calls:

Function greet (who) (console.log ("Hello," + who);) greet ("Semyon"); console.log ("Poked");

It is handled like this: calling greet makes the pass jump to the beginning of the function. It calls the built-in console.log function, which intercepts control, does its job, and returns control. Then he goes to the end of greet, and returns to the place where he was called from. The next line calls console.log again.

This can be shown schematically as follows:

Top greet console.log greet top console.log top

Since 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 go back to greet. In another, it goes back to the end of the program.

The place where the computer remembers the context is called the stack. Each time a function is called, the current context is pushed to the top of the stack. When the function returns, it pops the top context off the stack and uses it to continue.

Storing the stack requires memory space. When the stack grows too much, 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 difficult question, which leads to endless jumps between the 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 perfectly legal and runs without problems:

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

Officially, the function takes one argument. However, with such a call, she does not complain. She ignores the rest of the arguments and shows "Hello".

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

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 about it.

The good news 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 either two or one arguments - 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 will see how in the body of a function you can find out 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 question. What happens to local variables when a function stops working?

The following example illustrates this issue. It declares the wrapValue function, which creates a local variable. It then returns a function that reads this 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 legal and works as it should - access to the variable remains. Moreover, several instances of the same variable can exist at the same time, which once again confirms the fact that with each call of the function, local variables are recreated.

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 closure function. It not only frees you from the worries associated with the lifetime of variables, but 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 this way. A good 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 remote control for a piece of code that is frozen for later use.

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

Recursion

A function may well call itself as long as it takes care not to overflow the stack. This 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 it describes the concept more elegantly than a loop. The function calls itself many times with different arguments to achieve multiple multiplication.

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

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

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

The main rule, which has been repeated more than once, 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 don't get much simplicity from elegant solutions. Sometimes an experienced programmer will immediately see that a simple approach will never be fast enough.

I am focusing on this because too many beginner programmers grab efficiency even in the smallest detail. The result is bigger, more complex and often not without errors. Such programs take longer to write, and they often do not work much faster.

But recursion is not always just a less efficient alternative to loops. Some tasks are easier to solve with recursion. Most often, this is a traversal of several branches of the tree, 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, having received 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 cannot be obtained 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 — anyone can do it. I don't expect you to immediately understand how the program works. But let's get to grips with this great recursive thinking exercise.

The inner find function deals with recursion. It takes two arguments - the current number and a string that contains a record of how we arrived at this number. And it 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 exactly the way to achieve it, so it is returned. If the given number is greater than the goal, there is no point in continuing to multiply and add, because this way it will only increase. And if we haven't reached the goal yet, the function tries both possible paths, starting with the given number. She calls herself twice, once in each way. If the first call returns non-null, it is returned. Otherwise, a second is returned.

To better understand how the function achieves the desired effect, let's look at the 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 solutions starting with (1 + 5) and (1 * 3). The first call looks for a solution starting with (1 + 5) and recursively checks all solutions that return a number less than or equal to the required one. Does not find it, and returns null. Then the operator || and moves on to the function call, which examines the option (1 * 3). We're in luck here, because in the third recursive call we get 13. This call returns a string, and each of the || on the way passes this line up, resulting in returning the solution.

Growing 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 the repeating functionality, give it a 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 put into a separate function. You start with the name of the function and then write its body. You can even start by writing code that uses a function before the function itself is defined.

How difficult it is for you to find a name for a function shows how well you imagine its functionality. Let's take an example. We need to write a program that prints out 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 Chicken

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 the string, we get its length. It turns out that while loops add zeros in front of numbers until they get a line 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 pigs on his 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 understand that we need to stop and think. There must be a better way. We are trying to improve the program:

// output with ZeroPaddedWithLabel 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, adding zeros, and a label - into one function. Instead of nesting the entire repetitive chunk in 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 good, self-explanatory 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 features be? We can write both a simple function that complements a number with zeros to three positions, or a fancy function general purpose for number formatting, which supports fractions, negative numbers, dot alignment, character padding, etc.

A good rule of thumb is to add only the functionality that is most useful to you. It is sometimes 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 else 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 with a side effect: it prints out a string. Second, zeroPad, because of the return value. And it's no coincidence that the second function 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 function that returns a value, which not only has no side effects, but also does not depend on the side effects of the rest of the code - for example, it 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 with the result of its operation, 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 the given context, it will work in any one. Functions that are not so pure can return different results depending on many factors, and have side effects that are difficult to test and account for.

However, one should not hesitate to write not entirely pure functions, or start sacred cleaning of the code from such functions. Side effects are often helpful. There is no way to write a clean version of the 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, it 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, are recreated each time it is called, and are not visible from the outside. Functions declared inside another function have access to its scope.

It is very useful to separate the different tasks performed by the program into functions. You don't have to repeat yourself, functions make your code more readable by dividing it into meaningful parts, just as chapters and sections in a book help you organize regular text.

Exercises

Minimum
In the previous chapter, the Math.min function was mentioned, which returns the smallest of the 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% (modulo) operator can be used to determine if a number is even (% 2). And here's 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 at 50 and 75. Try setting it to -1. Why is she acting this way? Can you 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 the beans.

The character number N of a string can be obtained by appending .charAt (N) (“string” .charAt (5)) to it - similar to getting the length of a string using.length. The return value will be a string, consisting of one character (for example, “to”). The first character of the string has position 0, which means that the last character will have a position of string.length - 1. In other words, a string of two characters has a length of 2, and its character positions will be 0 and 1.

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

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

Jump Operators and Exception Handling

Jump operators are another category of JavaScript operators. As the name suggests, these operators 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. V JavaScript it is possible to mark instructions with names, so that it is possible to explicitly indicate in the break and continue statements which loop or other instruction they refer to.

The return statement causes the interpreter to jump from the called function back to the point of its call and return the value of the call. The throw statement throws an exception and is intended to work in conjunction with try / catch / finally statements that define a block program code to handle the exception. This is a rather complex 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 in the called function's return stack.

All of these jump operators are described in more detail in the following subsections.

Instruction Labels

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

identifier: instruction

By tagging an instruction, you give it a name, which you can then use as a reference anywhere in the program. You can mark any instruction, but only instructions with a body, such as loops and conditional statements, make sense to mark.

Once you give the loop a name, you can then use it in the break and continue statements, inside the loop to exit from it, or to go to the beginning of the loop, to the next iteration. The break and continue statements are the only JavaScript statements that can be labeled, and are discussed in more detail below. The following is an example of a while statement with a label and a continue statement using that label:

Mainloop: while (token! = Null) (// The program code is omitted ... continue mainloop; // Go to the next iteration of the named loop)

The identifier used as the instruction label can be any valid JavaScript identifier other than the reserved word. Label names are separate from variable and function names, so identifiers that match the names of variables or functions can be used as labels.

Instruction labels are only defined within the instructions to which they apply (and, of course, within the instructions nested within them). Nested instructions cannot be tagged with the same identifiers as the enclosing instructions, but two independent instructions can be tagged with the same tag. Tagged instructions can be tagged again. That is, any instruction can have multiple labels.

Break statement

The break statement causes an immediate exit from the innermost loop or switch statement. We have already seen examples of using the break statement inside a switch statement. In loops, it is usually used to exit the loop immediately when, for some reason, the loop needs to be terminated.

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

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

JavaScript allows you to specify the name of the tag behind keyword break (identifier without colon):

break tagname;

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

It is not allowed to insert a line feed character between the break keyword and the label name. The fact is that the JavaScript interpreter automatically inserts the missing semicolons: if you split a line of code between the break keyword and the next label, the interpreter will assume that it meant simple form this operator is unlabeled, and will add a semicolon.

A break statement with a label is needed only when you want to interrupt the execution of a statement that is not the nearest enclosing loop or switch statement.

The 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, both in the form without a label, and with a label, can only be used in the body of the loop. Using it elsewhere will result in a syntax error. When the continue statement is executed, the current loop iteration is interrupted and the next one begins. For different types cycles, this 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 executing the loop again.

    The for loop evaluates the increment expression and evaluates the test expression again to determine if the next iteration should be performed.

    In a for / in loop, the loop starts over, assigning the specified variable to the name of the next property.

Note the differences in the behavior of the continue statement in while and for loops. The while loop returns directly to its condition, and the for loop evaluates the increment expression first and then returns to the condition. The following example demonstrates the use of an unlabeled continue statement to exit the current loop iteration 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, and then the loop that is restarted will not necessarily be the loop that directly contains the continue statement. Also, as with break, line breaks between the continue keyword and the label name are not allowed.

Return statement

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

If the 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 calling program. 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 execution of the function and returns undefined to the calling program. 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 that indicates an exception or error has occurred. Throwing 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 a graduation.

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

The throw statement has the following syntax:

throw expression;

The expression can result in a value of any type. The throw statement can be passed a number representing an error code or a string containing the text of an error message. JavaScript interpreter throws exceptions using class instance Error one of its subclasses, and you can use a similar approach as well. The Error object has a property name defining the type of error and the property message 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:

// Number factorial function function factorial (number) (// If the input argument is not a valid value, // an exception is raised! 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 interrupts normal program execution and jumps to the closest exception handler. The exception handlers use the try / catch / finally catch statement, which is described in the next section.

If the block of code in which the exception was thrown does not have a corresponding catch clause, the interpreter parses the next outer block of code and checks to see if an exception handler is associated with it. This continues until a handler is found.

If an exception is thrown in a function that does not contain a try / catch / finally structure intended to handle it, then the exception is propagated higher into the program code that called the function. This is how exceptions are propagated through the lexical structure. JavaScript methods up the call stack. If an exception handler is still not found, the exception is treated as an error and reported to the user.

Try / catch / finally construct

The try / catch / finally construct implements the JavaScript exception handling mechanism. Try statement 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, called if an exception is thrown anywhere in the try block. The catch statement is followed by a block finally that contains the code that performs the final operations that are guaranteed to be executed no matter 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 with curly braces. This is a required part of the syntax and cannot be omitted, even if there is only one statement in between.

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

Try (// Usually this code runs smoothly from start to finish. // But at some point, an exception may be thrown in it // either directly using 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 is // thrown in the try block. These statements can use the local variable ex // referencing the Error object or any other value specified in the throw statement. // This block can either handle the exception in some way, // ignore it by doing something else, or rethrow // the exception using a throw statement.) Finally (// This block contains statements that are always executed, regardless of , // what happened in the try block. They are executed if the try block has finished: // 1) as usual, reaching the end of the block // 2) because of a break, continue or return statement // 3) with the exception handled is given in the catch block above // ​​4) with an uncaught exception that continues // propagating to higher levels)

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

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

Try (// Prompt the user for a number var n = Number (prompt ("Enter a positive number", "")); // Calculate the factorial of a number, assuming // that the input is correct 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 an 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 useful at times. The finally block is guaranteed to execute if at least some part of the try block was executed, regardless of how the code in the try block ended. This feature is typically used to perform post-code execution in the continuation of a try.

Ordinarily, control flows to the end of the try block and then continues to the finally block, which performs the necessary final operations. If control exits the try block as a result of a return, continue, or break statement, the finally block is executed before transferring control elsewhere.

If an exception is thrown in the try block and there is an appropriate catch block to handle it, control is first passed to the catch block and then to the finally block. If there is no local catch block, then control is first passed to the finally block and then flowed to the nearest outer catch block that can handle the exception.

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

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

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

The code placed in the function will be executed only after the explicit call of this function.

Function declaration

1.Syntax:

// Function declaration function FunctionName (ln1, ln2) (Function code) // Calling the function FunctionName (ln1, ln2);

2. Syntax:

// Function declaration var function name = function (ln1, ln2) (Function code) // Call the function function name (ln1, lv2);

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.

lane1 and lane2 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, do not forget to insert parentheses "()" after the function name.

Note: JavaScript function names are case sensitive.

JavaScript function example

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

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 over variables inside functions are actually performed not over the variables themselves, but over their copies, therefore the contents of the variables themselves do not change as a result of the execution of the functions.

/ * Let's 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 (" The value of the variable before the function call: "+ a +"
"); // Call the function by 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 and not 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

Using 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 embedded 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.

Upon completion of 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 the 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 destroyed only after the page is closed.

Quick view

Note: var2 will be empty when displayed, since func1 operates on a 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 normal functions, and to pass 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... Correct the errors in the code below:

Exercise 1

Correct the error in the code.

Assignment 2.

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

Assignment 2

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

Please enable JavaScript to use the Disqus commenting system.


2021
maccase.ru - Android. Brands. Iron. news