Руководство по функциям в JavaScript

В JavaScript функции можно определить двумя основными способами: с помощью выражений функций (Function Expression) и объявлений функций (Function Declaration).

Первый способ: Объявлений функций (Function Declaration).

Функция JavaScript объявляется при помощи ключевого слова function. Формат объявления функции имеет следующий вид:

function имя_функции ([аргументы]) {
    // тело функции
}
  • function - ключевое слово, при помощи которого объявляются функции;
  • имя_функции - уникальное в пределах сценария имя, идентифицирующее функцию. Для имен функций справедливы все те правила и требования, что и для имен переменных в JavaScript.
  • аргументы - аргументы служат для передачи функциям входных данных. При указании нескольких аргументов, они разделяются запятыми. Круглые скобки за именем функции обязательны, даже если функция не должна иметь аргументов.
  • тело функции - последовательность операторов JavaScript, выполняющих определенную задачу.

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

имя_функции ([параметры]);

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

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

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

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

<html>
	<head>
		<script type="text/javascript"> 
        <!-- 
            function cube(n) {
				var c=n*n*n; //вычисление куба числа 
				return c;    //возврат значения 
			}
        //-->
		</script>
	</head>
	<body>
		<script type="text/javascript"> 
        <!-- 
            var someNumber = 10;
			alert(2*cube(someNumber));
        //-->
		</script>
	</body>
</html>

Здесь очень важной особенностью объявления функций является "возвышение" (hoisting), что означает, что JavaScript автоматически перемещает объявление функции вверх до начала области видимости.

Второй способ: Объявлений функций (Function Expression).

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

Function Expression полезны, когда нужно передать функцию в качестве аргумента в другую функцию (например, функции высшего порядка).

Основная разница заключается во времени и доступности функций. Function Declaration позволяет использовать функцию перед ее определением благодаря поднятию. Function Expression требуют определения перед использованием и могут быть привязаны к областям видимости более точно с помощью переменных.

const greet = function(name) {
    console.log(`Hello, ${name}!`);
};
 
greet("Dmytro"); // Вызов функции после ее определения

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

Пример функции обратного (callback) вызова:

function doSomething(callback) {
    // ...
 
    // Call the callback
    callback('stuff', 'goes', 'here');
}
 
function foo(a, b, c) {
    // I'm the callback
    console.log("Call 1: " a + " " + b + " " + c);
}
 
doSomething(foo);
 
//Или можно вызвать так не создавая (не объявляя) отдельно function foo
doSomething(function (a, b, c) {
    console.log("Call 2: " +a + " " + b + " " + c);
})

В этом примере doSomething – это функция, принимающая функцию-колбек callback. После вычисления результата она вызывает колбек и передает ему результат.

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

В этих примерах мы видим, что функции-колбеки передаются в setTimeout и методы then объекта Promise для асинхронного кода.

// Асинхронный таймер
setTimeout(function () {
  console.log('Таймер вызвал этот колбек');
}, 1000);
 
// Асинхронный запрос к серверу
fetch('https://api.example.com/data')
  .then(function (response) {
    return response.json();
  })
  .then(function (data) {
    console.log('Данные с сервера:' + JSON.stringify(data));
  });

Асинхронные функции-колбеки являются мощным инструментом управления асинхронным кодом и событиями. Они используются для реализации обратного вызова, когда операция завершилась.

function fetchUserData(url, callback) {
  // Здесь мы имитируем асинхронный запрос к внешнему ресурсу (например, API)
  setTimeout(function () {
    const user = { name: 'Ivan', age: 28 };
    callback(user);
  }, 1000);
}
 
// Вызов функции с асинхронным колбеком.
// Вызов функции с передачей колбэка, который выполнится после получения данных
fetchUserData('https://api.example.com/user', function (user) {
  // Выводим полученные данные в консоль
  console.log('Полученные данные пользователя: ' + JSON.stringify(user));
});
 
Полученные данные пользователя: {"name":"Ivan","age":28}

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

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

function doSum() {
    let allSum = 0; // Локальная переменная, не глобальная
 
    return function(num) {
        allSum += num; // Увеличиваем сохранённую сумму
        return allSum;
    };
}
 
const sum = doSum(); // Создаём замыкание
 
console.log(sum(4));  // 4
console.log(sum(6));  // 10
console.log(sum(10)); // 20
console.log(sum(7));  // 27

🧠 Пояснение:

  • allSum — не глобальная переменная, она находится внутри doSum.
  • Но когда doSum() возвращает функцию, она «запоминает» переменные, которые были внутри.
  • Это и называется замыкание — функция «помнит» значение allSum между вызовами.

Анонимные функции в JavaScript - это функции, не имеющие имени или имени переменной и одноразовые или небольшие. Они полезны для выполнения одноразовых задач, создания функций-колбеков или захвата переменных в замыкании.

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

// Создание новой безымянной функции, используемой в качестве оболочки
(function(){
// Переменная, обычно имеющая глобальную область видимости
var msg = "Спасибо за визит!";
// Привязка к глобальному объекту новой функции,
window.onunload = function(){
// которая использует 'скрытую' переменную
alert( msg );
};
// Закрытие безымянной функции и ее выполнение
})();

Карринг (Currying) – это техника в функциональном программировании, которая заключается в трансформации функции со многими аргументами в последовательность функций с одним аргументом каждая. Это позволяет легко создавать новые функции с меньшим количеством аргументов и большим понятием кода. В JavaScript карринг реализуется с помощью замыканий.

В JavaScript есть три основных способа передавать параметры в функции:

  1. 1️⃣ Простые параметры (значения переменных) — используются, если аргументов мало и их порядок очевиден.
  2. 2️⃣ Массив как аргумент — удобен, если аргументы однородные (например, список чисел или имён) и порядок имеет значение.
  3. 3️⃣ Объект как аргумент — лучше всего подходит, если параметры разные, и их порядок не должен иметь значения, что делает код более читаемым и удобным для работы.

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

function calculateDiscount(price, discount = 0.15) {
    return price * (1 - discount);
}
 
console.log(calculateDiscount(200));     // Выведет 170 (при скидке 15%)
console.log(calculateDiscount(200, 0.25)); // Выведет 150 (при скидке 25%)

Деструктуризация (распаковка) параметров позволяет функции принимать аргументы в виде объекта или массива и сразу распаковывать их в отдельные переменные. Это особенно полезно при работе со сложными структурами данных.

function showProductDetails({ title, price, inStock }) {
    console.log(`Название: ${title}, Цена: ${price} руб., В наличии: ${inStock ? "Да" : "Нет"}`);
}

В этом примере объект product передается в функцию showProductDetails, которая сразу деструктуризует его в переменные title, price и inStock. Благодаря этому можно обращаться к нужным значениям напрямую, без необходимости писать product.title или product.price.

const product = { title: "Ноутбук", price: 35000, inStock: true };
showProductDetails(product); // Выведет "Название: Ноутбук, Цена: 35000 руб., В наличии: Да"

Стрелочные функции (arrow functions) — это упрощенный синтаксис для объявления функций в JavaScript. Они особенно удобны для кратких выражений и часто используются в функциональном программировании.

const arrowMathPlus = (a, b) => a + b;
const result = arrowMathPlus(3, 5); // результат: 8

В этом примере arrowMathPlus — это стрелочная функция, которая принимает два аргумента (`a` и `b`) и возвращает их сумму.

1. Краткий синтаксис Стрелочные функции не требуют ключевого слова `function`, а если тело функции состоит из одного выражения, можно опустить фигурные скобки `{}` и ключевое слово `return`.

const square = x => x * x;
console.log(square(4)); // 16

2. Нет собственного this Контекст вызова в JavaScript. В отличие от обычных функций, стрелочные функции не создают свой собственный контекст `this`, а используют значение `this` из внешней области видимости. Это делает их удобными при работе с методами объектов и колбэками.

Пример:

const user = {
    name: "Алекс",
    sayHello: function() {
        setTimeout(() => {
            console.log(`Привет, ${this.name}!`);
        }, 1000);
    }
};
 
user.sayHello(); // Через секунду выведет: "Привет, Алекс!"

Здесь стрелочная функция внутри `setTimeout` наследует `this` от метода `sayHello`, что позволяет правильно получить имя пользователя.

3. Отсутствие объекта `arguments` Стрелочные функции не имеют встроенного объекта `arguments`. Если нужно работать с аргументами, следует использовать оператор rest (`…args`). Для получения произвольного количества аргументов в функциях JavaScript используется оператор rest. Он обозначается тремя точками перед именем переменной и позволяет собрать все переданные аргументы в один массив.

Пример использования оператора rest в стрелочной функции:

const printAll = (...args) => {
  console.log(args);
};
 
printAll(10, 'hello', true);
// Вывод: [10, 'hello', true]

Когда использовать стрелочные функции?

  • Для коротких функций, особенно в обработчиках событий и колбэках:
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]
  • В методах `setTimeout` и `setInterval`, чтобы сохранить контекст `this`:
setTimeout(() => console.log("Прошло 2 секунды"), 2000);
  • В функциональном программировании, например, с `.map()`, `.filter()` и `.reduce()`.

Стрелочные функции делают код короче и понятнее, особенно при работе с колбэками и обработчиками событий. Однако их не следует использовать в качестве методов объектов или конструкторах, так как у них нет собственного `this`.

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

Самовызывающиеся функции, также известные как IIFE (Immediately Invoked Function Expressions), – это мощный инструмент в JavaScript, позволяющий создавать функции и вызывать их непосредственно после определения. Самовызывающиеся функции (IIFE) — это способ сразу вызвать функцию после её определения. Такой подход помогает изолировать переменные, создавая собственную область видимости и избегая конфликтов имён в глобальном контексте. Всё, что объявлено внутри IIFE, остаётся недоступным снаружи.

IIFE – это функция, которая определяется и вызывается сразу. Вот общий синтаксис IIFE:

(function() {
 // код функции
})();
  1. Определение функции размещается в круглых скобках, немедленно вызывающих ее для выполнения.
  2. Функция может быть анонимной, то есть, она не имеет имени.

Используйте IIFE для создания модульных компонент кода. Например, создадим модуль:

var myModule = (function() {
 var privateVar = 'Это приватная переменная';
 
 function privateFunction() {
 // Частная функция
 }
 
 return {
 publicVar: 'Это публичная переменная',
 publicFunction: function() {
 // Публичная функция
 },
 };
})();

Читайте также: Контекст вызова в JavaScript

📌 Для тестирования скриптов, установщиков VPN, Python ботов рекомендуем использовать надежные VPS на короткий срок. Если вам нужна помощь с более сложными задачами, вы можете найти фрилансера, который поможет с настройкой. Узнайте больше о быстрой аренде VPS для экспериментов и о фриланс-бирже для настройки VPS, WordPress. 📌

💥 Подпишись в Телеграм 💥 и задай вопрос по сайтам и хостингам бесплатно!