Вопросы для интервью по JavaScript для начинающих: примеры кода по определению области видимости переменных». — ЧАСТЬ 1
Что такое JavaScript?
JavaScript — это язык сценариев высокого уровня (Just-in-Time компилируемый язык), в основном используемый в веб-разработке. Он работает в веб-браузерах, позволяя разработчикам улучшать пользовательские интерфейсы за счет динамического контента, обработки событий и асинхронных операций. JavaScript поддерживает множество типов данных, функций и концепций объектно-ориентированного программирования. Он имеет решающее значение для взаимодействия на стороне клиента и имеет надежную экосистему библиотек и фреймворков.
Фрагменты кода JavaScript с пояснениями:
(function(){ setTimeout(() => console.log(1), 2000); console.log(2); setTimeout(() => console.log(3), 0); console.log(4); })();
Объяснение и выделенные функции JavaScript:
- Самозапускающаяся функция. Код начинается с немедленно вызываемого функционального выражения (IIFE), заключенного в круглые скобки
(function(){ ... })()
. Эта структура допускает инкапсуляцию и предотвращает переменное загрязнение в глобальной области видимости. - Асинхронные операции с
setTimeout
:setTimeout(() => console.log(1), 2000);
: Эта строка планирует выполнение функции обратного вызова после задержки в 2000 миллисекунд (2 секунды). Он демонстрирует асинхронное поведение, поскольку не блокирует выполнение остальной части кода. setTimeout(() => console.log(3), 0);
: Здесь функция обратного вызова запланирована с задержкой 0 миллисекунд. Это интересно, потому что даже при задержке, равной 0, не гарантируется немедленное выполнение из-за механизма цикла событий JavaScript.- Порядок выполнения:
console.log(2);
иconsole.log(4);
являются синхронными операциями, поэтому они выполняются немедленно при обнаружении в коде. console.log(2)
иconsole.log(4)
выводят значения2
и4
соответственно, и они регистрируются перед асинхронными операциями.- На первый взгляд порядок выполнения может показаться интуитивным, но асинхронность, введенная
setTimeout
, приводит к другому порядку протоколирования.
Порядок вывода консоли:
2
регистрируется немедленно, поскольку это синхронная операция.4
также немедленно регистрируется по той же причине.3
регистрируется раньше1
, хотя у него более короткий тайм-аут, поскольку он запланирован в другой «задаче» внутри цикла событий.- Наконец, после задержки в 2 секунды записывается
1
.
Этот код иллюстрирует ключевые функции JavaScript, такие как асинхронное программирование с использованием setTimeout
, цикл событий и порядок выполнения в неблокирующей среде. Это ценный пример для понимания того, как JavaScript обрабатывает параллелизм и синхронизацию в веб-приложениях.
function ¸() { for (var i = 0; i < 3; i++) { console.log(i); } console.log(i); } dummy()
Объяснение и выделенные функции JavaScript:
- Код определяет функцию JavaScript с именем
dummy
. Функции в JavaScript — это повторно используемые блоки кода. - Цикл for:Внутри функции
dummy
есть циклfor
. Этот цикл используется для многократного выполнения блока кода. - Область переменной: Переменная цикла
i
объявлена с использованиемvar
, что означает, что она имеет область действия на уровне функции. Это означает, чтоi
доступен как внутри, так и вне цикла внутри функцииdummy
.
0 1 2 3
- Цикл выполняется, пока
i
меньше3
, поэтому регистрируются0
,1
и2
. - После выхода из цикла строка
console.log(i);
вне цикла пытается записать значениеi
. Посколькуi
было объявлено с помощьюvar
, оно все еще существует в области действия функции, и его значение остается3
с последней итерации.
В этом примере кода показано использование цикла for
, области видимости переменных и способы доступа к переменным внутри и вне цикла. Это фундаментальная концепция JavaScript и программирования в целом.
function dummy() { for (let i = 0; i < 3; i++) { console.log(i); } console.log(i); }
Выход
0 1 2 Uncaught ReferenceError: i is not defined
Объяснение:
- Цикл работает как положено, регистрируя
0
,1
и2
во время трех итераций. - После выхода из цикла строка
console.log(i);
пытается записать значениеi
. Однако на этот раз результатReferenceError
. Это связано с тем, чтоi
имеет блочную область действия из-за использованияlet
и недоступен за пределами блока цикла.
Ключевой вывод
Использование let
в этом коде вводит область действия на уровне блока для переменной цикла i
, предотвращая доступ к ней вне цикла. Это существенное отличие от предыдущего фрагмента кода, где var
предоставлял область действия на уровне функции. Понимание области видимости переменных имеет решающее значение в JavaScript, особенно при работе с циклами и переменными уровня блока.
function dummy() { for (var i = 0; i < 3; i++) { setTimeout(function() { console.log(i); }); } console.log(i); }
Циклическое выполнение:
Цикл for
выполняется три раза, увеличивая i
с 0
до 2
. Однако важно отметить, что функция setTimeout
планирует выполнение анонимной функции, но не выполняет ее немедленно. Вместо этого он переходит к следующей итерации цикла.
Консольный вывод:
Когда вызывается функция dummy
, она выдает следующий результат:
3 3 3
Объяснение:
- Цикл выполняется три раза, каждый раз увеличивая
i
. - Функция
setTimeout
вызывается в цикле три раза, каждый раз планируя выполнение анонимной функции. - После выхода из цикла выполняется строка
console.log(i);
. Посколькуi
объявлен с помощьюvar
, он имеет область действия на уровне функции и сохраняет свое окончательное значение3
с последней итерации цикла. В результате3
регистрируется три раза.
Ключевой вывод:
Поведение setTimeout
в сочетании с функциональной областью действия var
может привести к неожиданным результатам. В этом примере все три запланированных оператора console.log
внутри функций setTimeout
печатают 3
, поскольку они ссылаются на одну и ту же переменную i
. Понимание замыканий и области видимости в JavaScript необходимо для эффективной работы с асинхронным кодом.
function dummy(){ for(let i=0;i<3;i++){ setTimeout(function()=>{ console.log(i); }) } console.log(i); }
Циклическое выполнение:
Цикл for
выполняется три раза, увеличивая i
с 0
до 2
. Каждая итерация планирует функцию setTimeout
с анонимной стрелочной функцией.
Консольный вывод:
Когда вызывается функция dummy
, она выдает следующий результат:
0 1 2 3
Объяснение:
- Цикл выполняется три раза, и во время каждой итерации он планирует функцию
setTimeout
, которая записывает значениеi
. Посколькуi
имеет блочную область действияlet
, каждая анонимная стрелочная функция «фиксирует» значениеi
в момент ее создания. - После планирования функций
setTimeout
цикл завершается и выполняется строкаconsole.log(i);
.i
по-прежнему доступен здесь и имеет значение3
, потому что это значение былоi
после завершения цикла.
Ключевой вывод:
Использование let
в этом коде гарантирует, что каждая анонимная стрелочная функция, созданная внутри цикла, фиксирует правильное значение i
на момент его определения. Это поведение отличается от примера var
и демонстрирует область действия на уровне блоков в JavaScript, что может помочь избежать распространенных проблем при работе с асинхронным кодом.
function sayHi() { console.log(name); console.log(age); var name = 'Nick'; let age = 21; } sayHi();
Консольный вывод
undefined 21
Объяснение:
- Оператор
console.log(name);
регистрируетundefined
дляname
, поскольку переменнаяname
объявлена с использованиемvar
. Переменные, объявленные с помощьюvar
, поднимаются, что означает, что они перемещаются в начало содержащей их функции или блока на этапе компиляции. Однако поднимается только объявление, а не инициализация. Итак,name
объявлен, но ему еще не присвоено значение при выполненииconsole.log(name);
. - Оператор
console.log(age);
регистрирует21
дляage
, поскольку объявленияlet
также поднимаются, но не инициализируются до того момента в коде, где они объявлены. В этом случаеage
объявляется и инициализируется значением21
в том же операторе, поэтому он доступен и сохраняет правильное значение при выполненииconsole.log(age);
.
Ключевой вывод:
Этот код иллюстрирует разницу в поведении переменных, объявленных с помощью var
, и переменных, объявленных с помощью let
, с точки зрения подъема и инициализации. Понимание этих различий имеет решающее значение для написания предсказуемого кода JavaScript.
(function() { var a = b = 5; })(); console.log(b);
Выражение функции с немедленным вызовом (IIFE):Код начинается с выражения функции с немедленным вызовом (IIFE), заключенного в круглые скобки (function() { ... })();
. IIFE — это способ создать функцию и немедленно выполнить ее.
Область действия и назначение переменной:
Когда var a = b = 5;
выполняется, происходит следующее:
var a
правильно объявлен и ему присвоено значение5
в области действия функции.b = 5
присваивает значение5
переменнойb
. Однако, посколькуb
объявлено безvar
илиlet
, оно становится неявной глобальной переменной (т. е. становится свойством глобального объекта, обычноwindow
в браузере).
Выход:
5
Объяснение:
- Оператор
console.log(b);
регистрирует5
, посколькуb
стала глобальной переменной из-за отсутствияvar
илиlet
в ее объявлении в IIFE. - Значение
5
, присвоенноеb
в IIFE, доступно в глобальной области, поэтому его можно зарегистрировать за пределами IIFE.
Важная заметка:
Хотя этот код работает так, как описано, обычно считается хорошей практикой явно объявлять переменные с использованием var
, let
или const
, чтобы избежать непреднамеренного создания глобальных переменных. В этом случае использование var a = 5; var b = 5;
в IIFE не позволило бы b
стать глобальной переменной.
(function() { 'use strict'; var a = window.b = 5; })(); console.log(b);
Строгий режим: строка 'use strict';
помещается в начало IIFE. Это активирует строгий режим для кода в IIFE. Строгий режим — это набор правил, которые делают JavaScript менее подверженным ошибкам и более безопасным.
Область действия и назначение переменной:
Когда var a = window.b = 5;
выполняется:
var a
правильно объявлен в области действия функции, и ему присвоено значение5
.window.b = 5
присваивает значение5
переменнойb
. Однако на этот раз он явно устанавливаетb
как свойство объектаwindow
. Это делаетb
глобальной переменной, доступной какwindow.b
.
Выход
5
Объяснение:
- Инструкция
console.log(b);
регистрирует5
, посколькуb
была явно назначена как глобальная переменная, прикрепленная к объектуwindow
в IIFE. - Благодаря строгому режиму код ведет себя так, как задумано, без создания каких-либо непреднамеренных глобальных переменных.
Важная заметка:
Хотя явное прикрепление свойств к объекту window
возможно, обычно это не рекомендуется, поскольку это может привести к загрязнению глобальных переменных и усложнить поддержку кода. Использование строгого режима помогает обнаружить такие непреднамеренные присвоения глобальных переменных и способствует улучшению практики кодирования.
function test() { console.log(a); console.log(foo()); var a = 1; function foo() { return 2; } } test();
var a = 1;
: Эта строка объявляет переменнуюa
с использованием ключевого словаvar
и присваивает ей значение1
. Переменные, объявленные с помощьюvar
, имеют область действия функции.function foo() { return 2; }
: Эта строка объявляет функцию с именемfoo
с использованием ключевого словаfunction
. Объявления функций также поднимаются, поэтому функция доступна для использования во всей области действия функции.
Выполнение кода:
Теперь давайте посмотрим, как выполняется код:
console.log(a);
: Эта строка пытается записать значениеa
на консоль до того, как ему будет присвоено значение. Поскольку объявленияvar
подняты,a
объявлен, но на данный момент еще не инициализирован. Итак,a
— этоundefined
.console.log(foo());
: Эта строка вызывает функциюfoo
и пытается зарегистрировать ее возвращаемое значение. Функцияfoo
возвращает2
, поэтому2
записывается в консоль.
undefined 2
Объяснение:
- Первый оператор
console.log(a);
регистрируетundefined
, посколькуa
объявлен сvar
и поднят, но еще не инициализирован. - Второй оператор
console.log(foo());
регистрирует2
, поскольку вызывается функцияfoo
и возвращает2
.
Ключевой вывод:
Этот код демонстрирует подъем переменных и объявления функций внутри функции JavaScript. Понимание подъема и области действия переменных/функций важно при работе с JavaScript, чтобы избежать неожиданного поведения.
Вывод:
В этом подробном руководстве по вопросам на собеседовании по JavaScript мы рассмотрели множество примеров кода и концепций, которые помогут вам подготовиться к предстоящим собеседованиям. Подведем итоги:
- Понимание областей действия. JavaScript имеет области действия на уровне функций и на уровне блоков. Переменные, объявленные с помощью
var
, имеют область действия на уровне функции, аlet
иconst
представляют область действия на уровне блока. Помните о том, как область видимости переменных влияет на ваш код. - Подъем. JavaScript поднимает объявления переменных и функций в начало области их содержания. Такое поведение может привести к неожиданностям, если вы не будете осторожны, поэтому очень важно понять, как оно работает.
- Глобальные переменные. Избегайте непреднамеренного создания глобальных переменных. Всегда объявляйте переменные с помощью
var
,let
илиconst
, чтобы контролировать их область действия и предотвратить загрязнение глобального пространства имен. - IIFE: выражения функций с немедленным вызовом (IIFE) – это мощный инструмент для создания изолированных областей в JavaScript. Они могут помочь предотвратить конфликты глобальных переменных и сохранить ясность кода.
- Строгий режим. Включите строгий режим в ваших скриптах с помощью
'use strict';
. Он обеспечивает более эффективные методы кодирования, выявляет распространенные ошибки и делает ваш код более предсказуемым. - Практика ведет к совершенству.Регулярная практика необходима для улучшения ваших навыков программирования. Решайте проблемы с кодированием, изучайте различные концепции JavaScript и пишите чистый и эффективный код.
- Ищите обратную связь. Не стесняйтесь обращаться за отзывами к коллегам, наставникам или онлайн-сообществам программистов. Конструктивная обратная связь может помочь вам определить области для улучшения.
- Сохраняйте уверенность. Уверенность – ключ к успеху на собеседовании. Сохраняйте спокойствие, четко формулируйте свой мыслительный процесс и не бойтесь задавать уточняющие вопросы, если вы не уверены в проблеме.
Изучая и практикуя примеры кода, представленные в этом руководстве, вы не только получите более глубокое понимание JavaScript, но и приобретете навыки и уверенность, необходимые для того, чтобы преуспеть на следующем техническом собеседовании. Помните, успех на собеседовании приходит с практикой и постоянным обучением. Желаем удачи на вашем пути кодирования!