Область видимости
Вы уже объявляете переменные, пишете функции и возвращаете значения. Ещё одно правило решает, доступно ли имя: область видимости (scope). Она отвечает: «отсюда какие имена мне можно использовать?»
Что значит область видимости
Это участок программы, где имя существует. Снаружи то же написание может быть невидимо — или указывать на другую привязку. Представьте комнаты: ярлык на стене кухни виден на кухне; на улице сам по себе не появляется.
Три повседневных вида
📊 Глобальная, функциональная и блочная область
| Вид | Где живёт имя | Типичные средства | Где видно? |
|---|---|---|---|
| глобальная | вне любой функции | let / const / var на верхнем уровне |
по всему скрипту (та же страница) |
| функциональная (локальная) | внутри тела функции | параметры и локальные | только внутри этой функции |
| блочная | внутри { } вроде if или цикла |
let и const |
только внутри этого блока |
Эти три покрывают большую часть кода новичка. Локальные функции остаются частными. Блочные привязки let/const остаются в фигурных скобках. Глобальные общие — удобны для общего счётчика, опасны, если всё становится глобальным.
let city = "Tehran";
function showCity() {
console.log(city);
}
showCity();
console.log(city);
Глобальные имена стоят вне функций
city объявлен на верхнем уровне, поэтому его читают и функция, и следующий console.log. Измените строку один раз — каждый читатель увидит новое значение. Глобальные — только когда несколько частей действительно делят одно значение.
function greet() {
let message = "Hello";
console.log(message);
}
greet();
// console.log(message); // Error: message is not defined
Локальные остаются в функции
message существует только пока выполняется greet. Снаружи это имя не определено. Параметры так же: локальны для функции, которая их перечисляет.
if (true) {
let score = 10;
console.log(score);
}
// console.log(score); // Error: score is not defined
let и const уважают блоки
Внутри { } привязка let или const видна только в этом блоке. После закрывающей скобки score исчезает. Старый var имеет функциональную область и может «утечь» из блока. Предпочитайте let и const, чтобы край блока значил то, что видно.
let title = "Shop";
function show() {
let label = "open";
console.log(title + " is " + label);
}
show();
Вложенность смотрит наружу
show читает внешний title и свой label. Поиск идёт наружу, пока не найдёт совпадение. Не внутрь: внешний код не видит имя, рождённое только внутри функции.
let status = "ok";
function check() {
let status = "busy";
console.log(status);
}
check();
console.log(status);
Затенение: внутри побеждает внутреннее
Внутри check локальный status скрывает внешний. Вызов печатает busy. После функции внешний всё ещё ok. Одна орфография, две привязки — область видимости решает, какую вы трогаете.
Показать значение с областью на странице
Держите глобальную метку, соберите в функции строку, которая ещё может её читать, и запишите результат в абзац.
<!DOCTYPE html>
<html>
<head>
<title>scope — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
let place = "Garden";
function line() {
let state = "open";
return place + " is " + state;
}
let box = document.getElementById("msg");
box.textContent = line();
</script>
</body>
</html>
Абзац показывает Garden is open. place глобален; state локален для line. Функция читает оба, возвращает строку, страница её показывает. Измените только place, обновите, прочитайте строку. Дальше: замыкания (closures) — функции, которые держат внешние имена живыми после внешнего вызова.
Практика
- Объявите глобальный
let app = "demo"и залогируйте из маленькой функции и снаружи. - Положите
let secret = 1в функцию; убедитесь, что логsecretснаружи даёт ошибку. - В
if (true) { }объявитеlet n = 5и залогируйте; попробуйте после блока. - Из вложенной функции прочитайте внешний
letбез повторного объявления. - Затените внешний
let tag = "A"внутреннимlet tag = "B"и залогируйте оба места. - В HTML-демо измените только строку
place, обновите, прочитайте абзац.
Частые ошибки
- Использовать локальное имя вне функции — ReferenceError, не тихое пусто
- Ждать, что
varв блоке останется частным какlet - Считать, что внешний код видит имена, рождённые только во вложенной функции
- Путать область видимости с
return— одно про видимость, другое про отдачу значения - Ждать здесь полный урок по closures — это следующая страница
Кратко
- Область видимости — где имя видно и используется
- Глобальные живут вне функций и общие на весь скрипт
- Локальные и параметры остаются в своей функции
letиconstв{ }блочные; лучше утекающегоvar- Вложенный код может читать наружу; снаружи не видно только-внутренних имён
- Внутренняя привязка с тем же именем затеняет внешнюю
- Обновление страницы может соединить глобальное и локальное в возвращённой строке
- Дальше: closures — функции, которые помнят внешние имена
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху