JavaScript functions. JavaScript functions Passing variables to functions

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 roots, etc.).

Code placed in a function will only be executed after an explicit call to this function.

Function Declaration

1. Syntax:

//Declaration of the function functionFunctionname(ln1, ln2)( Function code) //Calling the functionFunctionname(ln1,lr2);

2. Syntax:

//Declaration of the function var function name=function(ln1, ln2)(Function code) //Calling the function function name(ln1,lr2);

functionname 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 begin with numbers.

ln1 and ln2 are variables or values ​​that can be passed into the function. An unlimited number of variables can be passed to each function.

Please note: even if no variables are passed to the function, do not forget to insert parentheses "()" after the function name.

Please note that function names in JavaScript are case sensitive.

Example JavaScript functions

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

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

// The function writes text to the page function messageWrite() ( document.write("This text was written to the page using JavaScript!"); )

Passing Variables to Functions

You can pass an unlimited number of variables to functions.

Please note: all manipulations with 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 executing functions.

/* Let's define a function that adds 10 to the passed variable and displays the result on 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("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("The value of the variable before the function call: "+a+"
"); plus(a); document.write("Value of the variable after calling the function: "+a+"
");

Quick view

return command

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

//The sum function returns the sum of the variables passed to it function sum(v1,v2)( return v1+v2; ) document.write("5+6=" + sum(5,6) + "
"); document.write("10+4=" + sum(10,4) + "
");

Quick view

Built-in functions

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

For example, the built-in isFinite function allows you to check whether 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 You can find built-in JavaScript functions in our .

Local and global variables

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

After the function code completes execution, 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 destroyed only after the page is closed.

//Declare global variables var1 and var2 var var1="var1 exists"; var var2; function func1() ( //Assign var2 a value inside the function func1 var var2="var2 exists"; ) //From another function, print the contents of the variable var1 and var2 to the page function func2() ( //Print the contents of the variable var1 document.write( var1 + "
"); //Output the contents of the variable var2 document.write(var2); )

Quick view

Note that when printed to the screen, var2 will have an empty value 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 to be subsequently called from code like regular functions, but to be passed to other functions as a parameter.

Function arrMap(arr,func)( var res=new Array; for (var i=0;i 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 is satisfied by any. I don't expect you to immediately understand how the program works. But let's understand this great exercise in recursive thinking.

The inner function find does 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 story is precisely the way to achieve it, so it returns. If the given number is greater than the goal, there is no point in continuing to multiply and add, because 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 summons herself twice, once with each method. If the first call does not return null, it is returned. In another case, the second one is returned.

To better understand how the function achieves its desired effect, let's look at the calls it makes to find a solution to 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 uses recursion to check all solutions that produce a number less than or equal to the required number. Doesn't find it and returns null. Then the operator || and moves on to a function call that examines the (1 * 3) option. We're in luck here, because in the third recursive call we get 13. This call returns a string, and each of the || along the way it passes this line higher, resulting in returning a solution.

Growing functions There are two more or less natural way entering functions into the program.

The first is that you write similar code several 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, give it a good name, and put it into 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 has been 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 one occupies exactly three positions.

007 Cows 011 Chickens

Obviously, we need a function with two arguments. Let's start coding.
// print FarmInventory 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 while loops add leading zeros to numbers until you get a 3-character string.

Ready! But just as we were 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 a display 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:

// output WITH Adding Zeros AND Labels 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 bit strange. It combines three things—output, adding zeros, and a label—into one function. Instead of inserting an entire repeating fragment into a function, let's highlight one concept:

// add Zero 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, clear 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 the features be? We can write either a simple function that pads a number with zeros up to three positions, or a sophisticated function general purpose for formatting numbers, supporting fractions, negative numbers, dot alignment, padding with different characters, etc.

A good rule of thumb is to add only functionality that you know will be useful. Sometimes it's tempting to create general-purpose frameworks for every little need. Resist him. You'll never finish the job, you'll just end up writing a bunch of code that no one will use.

Functions and Side Effects Functions can be roughly divided into those that are called for their side effects and those that are called to obtain 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 it has a side effect: it prints a string. The second, zeroPad, because of the return value. And it’s not a 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 produce 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, it does not work with global variables that could be accidentally changed somewhere else. A pure function, when called with the same arguments, returns the same result (and does nothing else) - which is quite nice. She's easy to work with. A call to 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 a given context, it will work in any context. Less pure functions may return different results depending on many factors, and have side effects that are difficult to test and account for.

However, you should not be embarrassed to write functions that are not entirely pure, or to begin a sacred code cleansing of such functions. Side effects are often beneficial. 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.

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

The key to understanding functions is local scope. 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 a program into functions. You don't have to repeat yourself; functions make code more readable by dividing it into meaningful parts, just as chapters and sections of a book help organize regular text.

ExercisesMinimum In the previous chapter, we mentioned the Math.min function, which returns the smallest of its arguments. Now we can write such a function ourselves. Write min function, which 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 whether a number (%2) is even. Here's another way to define it:

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

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

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

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)); // → ??

Counting the 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 using .length. The return value will be a string consisting of one character (for example, “k”). The first character of a 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 function countBs that takes a string as an argument and returns the number of “B” characters contained in the string.

Then write a function called countChar, which works something like countBs, but 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, rework the countBs function.