Область действия относится к тому, где доступны переменные и функции и в каком контексте они выполняются.
Область действия переменной определяется расположением объявления переменной и определяет часть программы, в которой доступна переменная.
JavaScript имеет два типа областей видимости: глобальную и локальную. Глобально объявленные переменные, доступные в глобальной области видимости. Переменные, объявленные внутри функций, доступны только внутри этой функции и являются локальными переменными.
## Глобальные переменные
Любая переменная, объявленная глобально, или любые переменные, объявленные вне функции, называются глобальными переменными. Он доступен из любого места в коде.
var globalVariable = ‘globally’; function foo(){ // the global variable accessible inside a function console.log(globalVariable); // globally }
### нет переменной
Если переменные определены без `var` вне функций, они являются глобальной переменной. Переменная без `var` внутри функции будет искать цепочку областей видимости, пока не найдет переменную или не попадет в глобальную область видимости и не создаст ее.
// a variable declared globally var globalVariable = ‘globally’; // a variable without var belongs to global scope withoutVar = ‘globally, not declared globally’; function foo() { // a variable not declared so belgongs to its global scope withoutVarInsideFunction = “globally, not declared inside function”; console.log(‘Inside function:’); console.log(globalVariable); console.log(withoutVar); console.log(withoutVarInsideFunction); } foo(); console.log(‘Outside function:’); console.log(globalVariable); console.log(withoutVar); console.log(withoutVarInsideFunction);
## Локальные переменные
Локальная переменная — это когда она только что определена и доступна в функции.
JavaScript использует цепочки областей видимости, чтобы установить область действия для данной функции. Каждая определенная функция имеет свою собственную вложенную область. Любая функция, определенная внутри другой функции, имеет локальную область видимости, связанную с внешней функцией. Если у вас есть вложенные функции, внутренняя функция будет иметь доступ к содержащимся в них переменным функций и функциям.
function foo() { // local scope var localVariable = ‘local’; } // global scope console.log(localVariable); // Uncaught ReferenceError: localVariable is not defined // catch clause-scoped variable var globalVariable = ‘globally’; try { throw ‘inside of try’ } catch (globalVariable) { console.log(globalVariable); // inside of try } console.log(globalVariable); // globally
### Затенение переменных
Переменные, объявленные глобально, имеют глобальную область действия. Переменная, объявленная с функцией, ограничивается этой функцией и затеняет глобальные переменные с тем же именем.
Одна и та же переменная может быть указана на нескольких уровнях вложенной области, что называется «затенением». Внутренняя переменная затеняет внешнюю переменную. Независимо от затенения поиск области всегда начинается с самой внутренней области, выполняемой в данный момент, и продвигается наружу до первого совпадения и останавливается. Локальная переменная имеет более высокий приоритет, чем переменная из внешней области.
// global scope var globalVariable = ‘globally’; function shadow() { // local scope var globalVariable = ‘local scope’; console.log(globalVariable); // local scope } shadow(); // local scope // global scope var globalVariable = ‘globally’; function shadow(globalVariable) { // local scope console.log(globalVariable); // undefined } shadow(); // undefined // global scope var globalVariable = ‘globally’; function shadowInIf() { if (true) { var globalVariable = ‘local scope’ } console.log(globalVariable); // local scope } var globalVariable = ‘globally’; var foo = (function () { var globalVariable = ‘inside function’; return function () { // closure console.log(globalVariable); // inside function } })(); foo(); // inside function
# Объявление функции
Объявление функции определяет именованную функциональную переменную, не требуя назначения переменной.
function foo() { // code… }
# Функциональные выражения
Функциональное выражение определяет функцию как часть более крупного синтаксиса выражения. Определенные функции Функции Выражения могут быть именованными или анонимными.
// anonymous function expression var a = function() { // code… } // named function expression var f = function foo() { // code… } f(); // call the function // function name cannot access outeside foo(); // Uncaught ReferenceError // self invoking funciton expression // IIFE (immediately invoked function expression) (function bar() { // code… })();
# Подъем
«Объявления функций и функциональные переменные всегда перемещаются («поднимаются») интерпретатором JavaScript наверх своей области видимости».
a = ‘declared at end, assignment at top’ console.log(a); // declared at end, assignment at top var a;
эквивалентный поднятый код будет выглядеть так:
var a; a = ‘declared at end, assignment at top’; console.log(a); // declared at end, assignment at top
Объявление переменной поднимается, а присвоение переменной — нет.
JavaScript поднимает только объявление.
console.log(a); // undefined var a = ‘declaration and assignment at end’;
эквивалентный поднятый код будет выглядеть так:
var a; console.log(a); // undefined a = ‘declaration and assignment at end’;
Объявление функции поднимается.
foo(); // inside function function foo() { console.log(‘inside function’); }
эквивалентный поднятый код будет выглядеть так:
function foo() { console.log(‘inside function’); } foo (); // inside function
Сначала поднимаются функции, а затем объявление переменных.
var firstLine; function firstLine() { console.log(‘inside function’) } console.log(firstLine); // firstLine is a function // ƒ firstLine() { // console.log(‘inside function’) // }
эквивалентный поднятый код будет выглядеть так:
function firstLine() { console.log(‘inside function’) } var firstLine; console.log(firstLine); // firstLine is a function // ƒ firstLine() { // console.log(‘inside function’) // }
Сначала поднимаются функции, а затем объявление переменных, присваивание не поднимается.
var firstLine = ‘first line’; function firstLine() { console.log(‘inside function’) } console.log(firstLine); // first line // firstLine is a variable
эквивалентный поднятый код будет выглядеть так:
function firstLine() { console.log(‘inside function’) } var firstLine; firstLine = ‘first line’; console.log(firstLine); // first line
На этот раз результатом является значение переменной, потому что переменной было присвоено значение, которое переопределяет объявление функции.
Объявление переменной поднимается, но их выражения присваивания — нет.
foo(); // Uncaught TypeError: foo is not a function var foo = function () { console.log(‘inside function’); }
эквивалентный поднятый код будет выглядеть так:
var foo; foo(); // Uncaught TypeError: foo is not a function foo = function () { console.log(‘inside function’); }
Функции, назначенные переменным, не поднимаются.