☕ Что в коробке? Как работают функции в JavaScript

Знакомимся с фундаментальным строительным блоком любого приложения на JavaScript — функцией.
☕ Что в коробке? Как работают функции в JavaScript

Что такое функция

Функция это блок программы, который выполняет определенное действие, например, возводит в степень или складывает значения.

Представьте, что функция это коробка, и мы не знаем, что внутри нее. Мы только знаем, что она может делать. И когда нам надо совершить какое-либо действие, мы помещаем значения в эту коробку и она выполняет всю работу.

Результат действия функции можно применить в любом месте программы.

Как объявить функцию

Функция объявляется с помощью команды function. После чего мы именуем функцию и в скобках записываем ее параметры.

Синтаксис такой:

Синтаксис функции на JavaScript
        function имя(параметры) {
  тело функции (любые команды)
};
    

Например, функция, которая вызывает предупреждение:

Код функции с предупреждением
        function showMessage() {
  alert( 'Предупреждение!' );
};

    
Схема строения функции
Схема строения функции

Как вызвать функцию

Функцию вызывают по имени. Например, чтобы вызывать функцию из нашего примера, нужно после функции написать showAlert();

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека фронтендера»

Параметры и аргументы

Аргументы

Функции можно задать сколько угодно параметров, а потом передать им любые значения. Функция сама поймет, что необходимо сделать с этими значениями.

Например:

Пример использования параметров и аргументов
        function showMessage(from, text) { // параметра: from, text
  alert(from + ', ' + text);
};

showMessage('Привет', 'мне нравится proglib'); // Привет, Мне нравится proglib

    

В примере мы используем два параметра: from и text. Затем в теле функции соединяем from + ', ' + text. А снаружи функции присваиваем им аргументы и выводим на экран.

Передачи одной функции в другую

В функцию можно передать значение другой функции. Например:

Примеры передачи одной функции в другую
        function getDomNodesBySelector(selector) {
  return Array.from(document.querySelectorAll(selector));
};
document.querySelector('.total__button').addEventListener('click', applyDiscount);
let numDiscount = 15;
function applyDiscount() {
      let items = getDomNodesBySelector('.price-value');
      items.forEach(function(item){
            item.innerText = item.innerText - (item.innerText*numDiscount/100);
      });
};

    

В примере задано две функции:

  1. getDomNodesBySelector — преобразует найденные селекторы на веб странице в массив.
  2. applyDiscount — считает какую-то величину и берет данные для этого из функции getDomNodesBySelector.

Колбэки

Строки кода в языке JavaScript выполняются по очереди. Например:

Пример функций, которые выполняются по порядку
        function one(){
  console.log('один');
}
function two(){
  console.log('два');
}
one();//один
two();//два

    

Но бывают такие случаи, когда нам необходимо отсрочить функцию one() , чтобы первой выполнилась two() . Для этого можно использовать setTimeout.

Например:

Пример функций, которые выполняются не по порядку
        function one(){
setTimeout( function(){
    console.log(1);
  }, 500 );

  console.log('один');
}// функция выполнится через 500 миллисекунд

function two(){
  console.log('два');
}
first();//два
second();//один

    

Вызов функции с отсрочкой называется колбэк (callback).

Колбэк передают в виде параметра. Например:

Пример колбэка
        function myHomework(subject, callback) {
  alert(`Starting my ${subject} homework.`);
  callback();
}
function myHomeworkFinished(){
  alert('Finished my homework');
}
myHomework('math', myHomeworkFinished);

    

Функция myHomework имеет два параметра subject и callback.

Затем мы вызываем параметр subject, а параметр callback вызовем функцией myHomeworkFinished.

Когда код выполнится, появятся два предупреждения: Starting my math homework и Finished my homework.

Порядок вызова функций и колбэков
Порядок вызова функций и колбэков

Локальные переменные

Локальные переменные видны только внутри тела функции. За пределами функции эти переменные уже не работают.

Например:

Пример кода  с локальной переменной
        function showMessage() {
  let message = "Я локальная переменная"; // локальная переменная

  alert( message );
}

showMessage(); // Я локальная переменная

alert( message ); // <-- будет ошибка, так как переменная видна только внутри функции

    

В примере мы попытались вывести значение переменной message двумя способами: внутри функции путем вызова самой функции и путем вызова самой переменной.

В первом случае получаем результат работы функции.

Во втором случае получаем ошибку, потому что переменную видно только внутри функции.

Внешние переменные

Давайте возьмем пример выше. Оставим внутри функции значение переменной message. А за пределами функции заведем другую переменную и назовем ее message.

Пример кода с локальной и внешней переменной
        function showMessage() {
  let message = "Я локальная переменная"; // локальная переменная

  alert( message );
}
let message = "Я внешняя переменная"
showMessage(); // Я локальная переменная
alert( message ); //Я внешняя переменная

    

В коде у нас две переменные с одинаковым именем. Но наш сценарий будет считать их разными переменными.

В первом случае переменная будет видна программе только внутри функции showMessage() , во втором случае переменная будет видна всей программе.

Параметры по умолчанию

Когда мы указали параметр и не присвоили ему аргумент, то его значение будет undefined.

Например:

Пример кода с параметром по умолчанию
        function showMessage(from, text) { // параметра: from, text
  alert(from + ', ' + text);
}

showMessage('Привет', ); // Привет, undefined

    

В примере параметру text мы не передали значение аргумента. Поэтому в результате мы видим аргумент параметра from и undefined.

Возврат значения

Вернуть значение функции можно с помощью директивы return в теле функции. Например, напишем функцию, которая складывает два параметра.

Пример возврата значения функции с помощью директивы return
        function sum(a, b) {
  return a + b;
}

let result = sum(1, 2);
alert( result ); // 3

    

В примере мы говорим функции, что необходимо возвращать сумму значений аргументов с помощью директивы return.

Необходимо помнить, что после return выполнение операций в функции прекращается. Поэтому, с помощью return можно прерывать функции.

Функция, которая возвращает функцию

Функцию из предыдущего примера можно записать так:

Пример функции, которая возвращает функцию
        const generateSumFinder = () => {
  const sum = (a, b) => a + b;   
  return sum;                      
};

const sum = generateSumFinder();   
sum(1, 5); 

    

Что мы сделали:

  1. Создали переменную generateSumFinder и присвоили ей значение стрелочной функции. Когда мы видим значок =>, перед нами стрелочная функция.
  2. Внутри функции создали переменную sum. Это локальная переменная и видна только внутри функции и присвоили ей значение стрелочной функции, которая складывает аргументы a и b.
  3. Вернули переменную sum.
  4. За пределами функции создали переменную sum. Это внешняя переменная и она не зависит от переменной внутри функции. Этой переменной мы присвоили значение функции generateSumFinder.

Рекурсия

В рекурсии функция вызывает саму себя. Рекурсия достигается за счет конструкции if…else. Чтобы применить рекурсию нужно определить базовый и рекурсивный случай. Функция будет вызывать саму себя, пока результат не приведет к базовому случаю. В других случаях будет выполняться рекурсивный случай.

Например:

Пример рекурсии
        function countdown (i){
             if (i <=1){
                 return i;
             } else {
                 return i-1
             };
         };

         alert (countdown(1));

    

Функция будет вызываться каждый раз, пока значение ее параметра i больше 1 – это рекурсивный случай. Или вызывается при базовом случае при i<=1.

Перегрузка функций в JavaScript

У перегруженных функций одинаковые имена, но разные параметры. JavaScript не поддерживает перегрузку.

Например:

Пример функции без перегрузки 
        function overload(a){
    console.log(«Параметр»)
}

function overload(a,b){
    console.log(«Два параметра»)
}
overload(1);      // Два параметра
overload(1,2);    // Два параметра

    

Несмотря на то, что в первой функции один параметр, вывод аргументов этой функции выведет два параметра. Как вы помните, второй ее параметр будет undefined.

В JavaScript есть способы, как перегрузить функцию. Для этого используют метод arguments.length.

Например:

Пример функции с перегрузкой 
        function overload () {
  if (arguments.length === 1) {
    console.log(«Параметр»)
  }
  if (arguments.length === 2) {
    console.log(«Два параметра»)
  }
}
overload(1);      // Один параметр
overload(1, 2);  // Два параметра

    

В примере с помощью метода arguments.length мы узнаем количество параметров в функции и выводим столько параметров, сколько аргументов мы задаем.

Выбор имени функции

Чтобы выбрать имя функции, необходимо следовать правилам:

Использовать слова на английском языке

неправильно правильно
pokazatSoobsheniye showMessage

Использовать глаголы, потому что функция – это действие

неправильно правильно
Message (сообщение) showMessage (показать сообщение)

Комментарии в функции

Комментарии нужны, чтобы кто-то кроме вас понимал, что происходит в функции.

Например:

Пример комментария в функции
        function getDomNodesBySelector(selector) {
  return Array.from(document.querySelectorAll(selector));
};// функция возвращает массив, который она возьмет из списка DOM узлов по указанному селектору. 

    

Замыкания

Замыкание – это функция, которая запоминает свои внешние переменные и может получить к ним доступ. В JavaScript все функции являются замыканиями. Замыкания позволяют функции работать с внешними переменными, даже если они изменились.

Например:

Пример замыкания функции на внешней переменной
        let name = "Nikolay";

function sayHi() {
  alert("Hi, " + name);
}

name = "Irina";

sayHi();//Hi, Irina
    

В примере функция sayHi() будет оперировать со вторым значением переменной name. Таким образом, функция замыкает свое действие на известной переменной, где бы не задали ее значение.

Приведем еще один пример:

Пример замыкания функции на внутренней переменной
        function makeWorker() {
  let name = "Nikolay";

  return function() {
    alert(name);
  };
}

let name = "Irina";

// create a function
let work = makeWorker();

// call it
work(); //Nikolay

    

В примере функция makeWorker() замыкается на внутренней переменной name = "Nikolay". Поэтому при инициализации переменных, следует обращать внимание, какая функция будет ими пользоваться и на какой из них будет замыкаться.

Стрелочные функции

Функцию можно задать не только с помощью слова function. Есть способ короче, для этого используют значок =>.

Например:

Пример функции, которая складывает параметры a и b
        let sum = (a, b) => a + b;

    

Если параметр в функции один, то скобки можно не писать.

Например:

Пример записи стрелочной функции с одним параметром n
        let double = n => n * 2;
alert(double(3))//6

    

Если параметров нет, то пишут круглые скобки.

Например:

Пример стрелочной функции без параметров
        let sayHi = () => alert("Hello!");

sayHi();//Hello!

    

Лексика this

В стрелочных функциях нет лексики this. Если происходит обращение к this, его значение берется снаружи.

Например:

Пример использования this в стрелочной функции
        let object = {
  title: "our object",
  students: ["Nikolay", "Irina", "Roma"],

  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};

object.showList();

    
***

Функции используются, чтобы они выполняли любые действия. Функции позволяют разбить код на блоки, исходя из логики программы. Чтобы овладеть написанием функций, необходимо понимать принципы их работы:

  • видимость переменных;
  • параметры и аргументы;
  • стрелочные функции;
  • лексика this;
  • замыкания;
  • рекурсия;
  • колбэки.

Материалы по теме

МЕРОПРИЯТИЯ

Комментарии

ВАКАНСИИ

Добавить вакансию
Java Team Lead
Москва, по итогам собеседования
Go-разработчик
по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ