Валерий Шестернин
Функции играют важную роль в структурировании и организации кода на JavaScript, его модульности, повторного использования и идиоматического стиля программирования. В данной статье мы рассмотрим понятие функции, способы их объявления, а также осветим некоторые особенности функций, введённые в современных версиях JavaScript.
Определение функции в JavaScript
Функции в JavaScript - это блоки кода, которые могут быть вызваны для выполнения определенных задач. Они представляют собой участки кода, которые могут принимать параметры (входные данные для описания функции), выполнять определенные операции и возвращать результат (выходные данные). Любая функция в JavaScript является объектом, а следовательно может быть передана в виде аргумента (входные данные для выполнения функции) другой функции, быть возвращена в качестве результата работы другой функции и присвоена в качестве значения переменной или свойства объекта. Далее мы рассмотри способы объявления функций и разницу между ними.
Function Declarations: базовое объявление функции
Функцию можно объявить с помощью ключевого слова function
через пробел после которого идет название функции, скобки с перечисленными внутри параметрами и фигурные скобки с описанием кода, который будет срабатывать при вызове функции. При таком объявлении функция вернет значение только если оно указано после инструкции return
а вызвать функцию можно из любой части кода (даже до объявления самой функции) указав ее имя и после него в скобках аргументы.
//вызываем функцию до объявления
console.log(greeting("Stan"));//The name is Stan
//в консоли так же выведется Hello Stan!
function greeting(name) {
//в фигурных скобках описывается код,
//который будет исполнен при вызове функции
console.log("Hello " + name + "!");
return "The name is " + name;}
В теле функции (внутри фигурных скобок после перечня параметров) может быть записан любой код с созданием условий, объектов и даже других функций. Выходные данные могут зависеть от этих условий, аргументов или хода исполнения кода в теле функции поэтому исполнение кода прекращается после первой выполненной инструкции `return`.function checkDay(day) {
if (day === "Saturday" || day === "Sunday") {
return "Weekend";//возвращаемое значение при
} //выполнении условия
return "Weekday";//возвращаемое значение при
} //невыполнении условия
Function Expressions: функциональные выражения
Как мы уже знаем, функция это объект, а значит может быть задана в качестве значения переменной (”const a = function b(){}
”). При таком объявлении мы получаем возможность присвоить функцию в качестве свойства объекта и создавать безымянные функции, которые будут вызываться через имя переменной или свойства объекта, которым они присвоены как значения.
myObj.sayHello = function () {//создаем безымянную функцию
console.log("Hello!");
};//передадим эту функцию как значение свойства
myObj.sayHello(); //Hello!
Важно помнить что функции, объявленые через Function Expressions, в отличии от Function Declarations можно вызвать только после их описания в коде. При этом вызвать их можно только через имя переменной или свойства, которой они присвоены. Имя самой функции доступно только внутри нее. Это полезно, например, для создания рекурсивных функций, которые вызывают сами себя до выполнения определенного условия.a(); //Cannot access 'a' before initialization
//нельзя получить доступ к переменной до ее создания
const a = function sayHello() {
console.log("Hello!");
sayHello();//функция доступна по имени внутри себя самой
};
sayHello(); //sayHello is not defined
//наша функция хранится только в переменной
//и не может быть вызвана по своему имени
Arrow Functions: стрелочные функции
У обоих предыдущих способов объявления функции есть недостатки. Во-первых значение объекта контекста this для таких функций определяется в зависимости от многих факторов (новый объект в случае конструктора, undefined в strict mode, контекстный объект, если функция вызвана как метод объекта, и т.д.) и это приходится отслеживать для каждой функции. Во-вторых длинный синтаксис с ключевым словом function и обязательным заключением тела функции в фигурные скобки. Оба недостатка исправлены в стрелочных функциях для которых this явно определяется окружающим функцию контекстом, а синтаксис в самом минимальном виде представляет собой набор параметров в скобках и “стрелка” из знаков равно и закрывающей угловой скобки (”()⇒
”).
const user = {
name: "John",
regularHello: function () {
console.log("Hello, " + this.name);
},
arrowHello: () => console.log("Hello, " + this.name),
outsideRegularFunc: function () {
const insideArrowFunc = () => {
console.log("Hello, " + this.name);
};
insideArrowFunc();
},
};
user.regularHello(); //Hello, John
//обычная функция получает в качестве this сам объект user
//и поэтому this.name для нее равен 'John'
user.arrowHello(); //Hello, undefined
//для этой стрелочной функции this не указан явно
//поэтому this.name неопределен (undefined)
user.outsideRegularFunc(); //Hello, John
//эта стрелочная функция берет this из своего контекста,
//которым является функция outsideRegularFunc
Кроме того все стрелочные функции безымянны и в них могут быть объявлены выходные данные без явного указания инструкции `return`.//попытка дать название стрелочной функции
const myFunc = namedFunc () => {}
//приведет к ошибке Malformed arrow function parameter list
const square = (num) => { return num * num };
const square2 = (num) => num * num;
//эти две записи идентичны
IIFE: Самовызывающиеся функции
Любую функцию можно вызвать сразу после объявления с помощью синтаксиса самовызывающихся функций. Он немного отличается для каждого вида объявления функции, но всегда предполагает заключение параметров, тела функции и ключевого слова function
в скобки и передачу аргументов после данной записи.
Следует помнить что самовызывающиеся функции не выйдет использовать повторно в другом участке кода.
//самовызывающаяся Function Declarations
(function sayHello(name) {
console.log("Hello, " + name);
})("John"); //Hello, John
//самовызывающаяся Function Expressions
const myFunc = (function sayHello(name) {
console.log("Hello, " + name);
})("Stan"); //Hello, Stan
//самовызывающаяся стрелочная функция
const sayHello = ((name) => {
console.log("Hello, " + name);
})("Tom"); //Hello, Tom
sayHello(); //Ошибка: sayHello is not a function
myFunc(); //Ошибка: myFunc is not a function
//при этом использовать эти функции впоследсивии
//не выйдет потому что они не определены
console.log(typeof sayHello); //undefined
console.log(typeof myFunc); //undefined
Параметры и аргументы функций
Мы уже знаем что параметры функции это описание входных данных при объявлении функции, а аргументы это входные данные при ее вызове. В качестве параметров или аргументов могут быть переданы любые типы данных и о том как эти данные внутри тела функции взаимодействуют с внешним кодом у меня есть отдельная статья, а сейчас лучше рассмотрим другие их свойства.
Во всех предыдущих примерах мы или вовсе не передавали аргументы в функцию или описывали каждый параметр при объявлении и работали с ним отдельно, но иногда мы хотим что бы функция могла принимать любое количество аргументов. Для таких случаев можно воспользоваться объектом arguments
внутри тела функции. Это подобный массиву объект, который содержит аргументы, переданные в функцию. Как и с обычным массивом мы можем получить его длину, обращаться к его элементам и т.д.
Кроме того, при объявлении параметров мы можем задать для значения по-умолчанию, которые будут присвоены, если аргумент не передан.
function logger() {
//используем в цикле arguments
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);}}
logger(1, 2, 3, 4, 5); //выведет все числа по-очереди
const power = (num, pow = 1) => num ** pow;
power(2, 2); //4
//второй аргумент передан и 2 возведена во вторую степень
power(2); //2
//второй аргумент не передаи и 2 возведена в первую степень
Заключение
Функции в JavaScript представляют собой мощный и гибкий инструмент, который необходимо правильно понимать и уметь использовать. Они помогают упростить и структурировать код, улучшить его читаемость и модульность. Умение работать с функциями в JavaScript является очень важным для любого разработчика. 
Карта развития разработчика
Получите полную карту развития разработчика по всем направлениям: frontend, backend, devops, mobile
Комментарии
0