Найти в Дзене
Как там в IT?

Подготовка к собеседованию - JavaScript. Часть 2: Функции и контекст

Вторая статья из серии, посвящённой ключевым темам JavaScript для технического интервью. Сегодня говорим о функциях — главных строительных блоках языка, а также о контексте вызова (this), замыканиях и областях видимости. Функции в JavaScript — это не просто подпрограммы. Они могут быть объявлены по-разному, иметь собственный контекст, «запоминать» окружение, в котором были созданы, и даже выступать в роли конструкторов. На собеседовании вам почти наверняка зададут вопросы о типах функций, о том, как работает this, и что такое замыкание. Без чёткого понимания этих тем сложно претендовать на позицию выше Junior. В этой статье разберём: Материал будет полезен как начинающим, так и тем, кто хочет систематизировать знания перед интервью. Приступим. В JavaScript есть несколько способов создать функцию. Выбор влияет на момент создания (hoisting), значение this внутри функции и возможность использовать её как конструктор. Особенности: Особенности: Особенности: В JavaScript все параметры являют
Оглавление

Вторая статья из серии, посвящённой ключевым темам JavaScript для технического интервью. Сегодня говорим о функциях — главных строительных блоках языка, а также о контексте вызова (this), замыканиях и областях видимости.

Введение

Функции в JavaScript — это не просто подпрограммы. Они могут быть объявлены по-разному, иметь собственный контекст, «запоминать» окружение, в котором были созданы, и даже выступать в роли конструкторов. На собеседовании вам почти наверняка зададут вопросы о типах функций, о том, как работает this, и что такое замыкание. Без чёткого понимания этих тем сложно претендовать на позицию выше Junior.

В этой статье разберём:

  • Способы объявления функций: Function Declaration, Function Expression, стрелочные функции — в чём различия.
  • Параметры функции: обязательные, необязательные, значения по умолчанию, arguments и rest-параметры.
  • Контекст выполнения (this): как он определяется в разных ситуациях и как его можно изменить.
  • Замыкания (closures): что это, как работают и где применяются.
  • Лексическое окружение и область видимости: внутреннее устройство, которое объясняет поведение переменных.

Материал будет полезен как начинающим, так и тем, кто хочет систематизировать знания перед интервью. Приступим.

1. Способы объявления функций

В JavaScript есть несколько способов создать функцию. Выбор влияет на момент создания (hoisting), значение this внутри функции и возможность использовать её как конструктор.

1.1 Function Declaration (объявление функции)

-2

Особенности:

  • Поднимается (hoisting) полностью: можно вызвать до объявления.
  • Имеет собственный контекст this (определяется вызовом).
  • Можно использовать как конструктор (с new).
  • Всегда имеет имя (отображается в стеке вызовов).

1.2 Function Expression (функциональное выражение)

-3

Особенности:

  • Не поднимается (hoisting) — переменная sum будет объявлена, но функция присвоится только во время выполнения.
  • Может быть анонимной или именованной (для рекурсии или отладки).
  • this определяется так же, как в Declaration.

1.3 Стрелочные функции (arrow functions)

-4

Особенности:

  • Не имеют своего this, берут его из внешнего лексического окружения.
  • Не могут быть вызваны с new (не являются конструкторами).
  • Не имеют объекта arguments (но можно использовать rest-параметры).
  • Синтаксически короче, особенно для однострочных выражений.
  • Не поднимаются (ведут себя как Function Expression).

2. Параметры функции

2.1 Обязательные и необязательные параметры

В JavaScript все параметры являются необязательными. Если параметр не передан, его значение — undefined.

-5

2.2 Значения параметров по умолчанию (ES6)

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

-6

Значения по умолчанию вычисляются в момент вызова, и в выражении можно использовать предыдущие параметры:

-7

2.3 Объект arguments

Внутри каждой не-стрелочной функции доступен псевдомассив arguments, содержащий все переданные аргументы (даже если они не объявлены в параметрах).

-8

arguments не является настоящим массивом, но имеет свойство length и индексы. В современном коде его часто заменяют rest-параметрами.

2.4 Rest-параметры (ES6)

Позволяют собрать оставшиеся аргументы в настоящий массив.

-9

Rest-параметр должен быть последним в списке.

3. Контекст выполнения (this)

this — одно из самых запутанных мест в JavaScript. Его значение определяется не тем, где функция написана, а тем, как она вызвана.

3.1 Глобальный контекст

В браузере на верхнем уровне this ссылается на глобальный объект window. В Node.js — на объект global (в модулях — на module.exports).

-10

3.2 Обычный вызов функции

Если функция вызывается как обычная (не как метод), в нестрогом режиме this становится глобальным объектом, в строгом — undefined.

-11

3.3 Вызов как метода объекта

Когда функция вызывается как свойство объекта, this ссылается на этот объект.

-12

Важно: если метод присвоить переменной и вызвать отдельно, контекст потеряется.

-13

3.4 Вызов с new (конструктор)

При вызове функции с new создаётся новый объект, и this ссылается на него.

-14

3.5 Явное связывание: call, apply, bind

Методы функции позволяют явно задать this:

  • call(thisArg, arg1, arg2, ...) — вызывает функцию с указанным this и аргументами.
  • apply(thisArg, [args]) — то же, но аргументы передаются массивом.
  • bind(thisArg, ...args) — возвращает новую функцию с навсегда привязанным this (и, опционально, частью аргументов).
-15

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

У стрелочных функций нет своего this. Внутри них this берётся из внешнего лексического окружения (там, где функция была определена).

-16

Поэтому стрелочные функции не подходят для методов объектов, если нужен доступ к объекту через this. Зато они удобны для колбэков, чтобы сохранить внешний контекст.

4. Лексическое окружение и область видимости

Каждый раз, когда выполняется код, создаётся лексическое окружение — внутренняя структура, которая хранит локальные переменные и ссылку на внешнее окружение. Область видимости определяется тем, где переменная объявлена.

4.1 Глобальное окружение

Создаётся при запуске скрипта, хранит глобальные переменные.

4.2 Функциональное окружение

Создаётся при каждом вызове функции, хранит локальные переменные, параметры, arguments и ссылку на внешнее окружение (где функция была определена).

4.3 Блочная область видимости (let, const)

Переменные, объявленные через let и const, существуют только внутри блока {...}. var этого не делает.

Пример:

-17

Цепочка окружений: inner → outer → global.

5. Замыкания (Closures)

Замыкание — это функция, которая «запоминает» своё лексическое окружение даже после того, как внешняя функция завершила работу.

5.1 Как это работает

Когда функция определяется внутри другой функции, она получает ссылку на внешнее окружение. Даже если внешняя функция вернулась, внутренняя сохраняет доступ к переменным внешней.

-18

Переменная count продолжает существовать, потому что на неё ссылается возвращённая функция. Это и есть замыкание.

5.2 Практическое применение

  • Инкапсуляция данных (приватные переменные).
  • Функции-фабрики.
  • Каррирование.
  • Обработчики событий, где нужно сохранить состояние.

Пример инкапсуляции:

-19

5.3 Замыкания в циклах (классическая проблема)

-20

Почему? Потому что var создаёт одну переменную на всю функцию, и к моменту выполнения колбэков цикл уже завершился, i равно 3. Решения:

  • Использовать let (создаёт новую переменную на каждой итерации).
  • Обернуть в замыкание (IIFE).
-21

6. Дополнительные вопросы на собеседовании

  • В чём разница между параметрами и аргументами?
    Параметры — это переменные в определении функции, аргументы — конкретные значения при вызове.
  • Что такое IIFE (Immediately Invoked Function Expression)?
    Функция, которая выполняется сразу после объявления. Используется для изоляции области видимости.
-22
  • Что произойдёт, если вызвать функцию с new и без?
    Без new — обычный вызов, this зависит от контекста. С new — создаётся новый объект, прототип устанавливается, и this ссылается на этот объект. Если функция явно не возвращает объект, возвращается this.
  • Можно ли привязать this стрелочной функции?
    Нет, call, apply, bind не влияют на this стрелочной функции — он всегда берётся из внешнего контекста.

Заключение

Мы разобрали одну из самых объёмных тем в JavaScript — функции и контекст. Теперь вы знаете:

  • как объявлять функции и чем различаются способы;
  • как работают параметры и rest-оператор;
  • что такое this и как им управлять;
  • что лежит в основе областей видимости — лексическое окружение;
  • что такое замыкания и где они применяются.

Эти знания обязательно проверят на собеседовании, причём не только в теории, но и в задачах на понимание кода. Потренируйтесь на Codewars или аналогичных платформах, чтобы закрепить.

В следующей статье серии «JavaScript: подготовка к собеседованию» перейдём к объектам и прототипам — ещё одному важнейшему блоку. Подписывайтесь, чтобы не пропустить!

Вопросы для самопроверки:

  1. Чем Function Declaration отличается от Function Expression?
  2. Какое значение будет у this в стрелочной функции, вызванной как метод объекта?
  3. Что выведет следующий код?
-23

4. Как изменить контекст функции greet так, чтобы она вывела 'Hello, Alice'?

-24

5. Почему в цикле с var и setTimeout все колбэки видят одно и то же значение?