Skip to content

5. Scope (области видимости)

Igor Demin edited this page Nov 3, 2023 · 5 revisions

image

Есть глобальные переменные и локльные переменные. Заметим что в глобальной области видимости и локальных есть переменные с одинаковыми названиями, это разные переменные. Если мы попытаемся обратиться к переменной b в Локальной области видимости 2, то переменная будет взята из неё. Если же мы в Локальной области видимости 1 вызовем переменную b то она будет взята из глобальной области видимости.

т.е. есть глобальные переменные и локальные переменные.

ПРИМЕР:

let a
let b

function myFn() {
  let b
  a = true
  b = 10
  console.log(b)
}

myFn() // вызовет функцию и покажет что внутри локальной области - console.log(b) 10

console.log(a) // true
console.log(b) // undefined

Цепочка областей видимости

image

ПРИМЕР: в данном примере вызов функции innerFn() внутри myFn() выполнится и покажет 5 т.к. сначала попытается найти её в своей локальной области видимоси и не найдя её возьмет переменную a из глобальной области т.к. там мы её объявили.
Когда мы вызовем её из глобальной области видимости получим ошибку т.к. функция не видна в глобальной области видимости.

const a = 5

function myFn() {
  function innerFn() {
    console.log(a)
  }
  innerFn() // если убрать вызов этой функции то вызов ниже myFn ничего не покажет т.к. функция innerFn только объявлена выше, но не вызывается.
}

myFn() // 5
innerFn() // ReferenceError: innerFn is not defined

Жизненный цикл переменных

Рассмотрим подробнее переменную b

let a
let b // 1. Объявление "b" в глобальной области видимости. Её значение в данный момент Undefined

function myFn() {
  let b // 3. Объявление "b" в зоне видимости функции
  a = true
  b = 10 // 4. Объявлена ли переменная в зоне видимости функции? - Да. Тогда присваиваем "b" значение 10 
  console.log(b) // 5. "b" имеет значение 10 в области видимости этой функции, это и покажет console.log
}

myFn()  // 2. Вызов myFn

console.log(a) 
console.log(b) // 6. "b" все так же имеет значение Undefined в глобальной области видимости

Переменная "b" тут была объявлена и ей присвоено значение только в области видимости myFn(), поэтому она там появился -> отработала -> после выполнения функции удалена.

Рассмотрим подробнее переменную a

let a // 1. Объявление "a" в глобальной области и её значение Undefined
let b 

function myFn() {
  let b 
  a = true // 3. Объявлена ли "a" в зоне функции? - Нет. Объявлена ли "a" во внешней зоне? - Да. Присваиваем значение "true" глобальной переменной "a"
  b = 10  
  console.log(b) 
}

myFn()  // 2. Вызов myFn

console.log(a) // 4. "a" имеет значение "true"
console.log(b) 

В данном примере мы во время выполнения функции присвоили значение глобальной переменной (что крайне не рекомендуется) "a" и это значение у неё осталось. И всё это потому, что мы не объявили её в области видимости функции чтобы она после выполнения функции удалилась. Чтобы этого избежать, нужно объявлять переменные внутри функции.

ВАЖНО: переменные сначала пытаются определиться в локальной области видимости и только не обнаружив их там переходят в глобальную область видимости т.к. функция была вызвана в глобальной области видимости.

Типы областей видимости

image

Блок это код который находиться в фигурных скобках

ПРИМЕР: В данном примере переменная "a" не была объявлена ни в одной области видимости, но после выполнения функции будет автоматически объявлена в глобальной области видимости(не в области видимости функции). Так делать настоятельно не рекомендуется!

function myFn () {
  a = true
  console.log(a)
}

myFn()

console.log(a)

Строгий режим strict mode

Это инструкция интерпретатору JS следить за кодом внимательнее, чтобы его использовать нужно включать путём добавления строки 'use strict'. Он запретит использовать необъявленные переменные в данном случае(но не только). И тогда получим ошибку ReferenceError: a is not defined.

'use strict'

function myFn () {
  a = true // ReferenceError: a is not defined
  console.log(a)
}

myFn()

console.log(a)

Эта строка может использоваться как в глобальной области видимости так и только в области видимости например функции, главное в самом начале.

function myFn () {
  'use strict'
  a = true // ReferenceError: a is not defined
  console.log(a)
}