let const - garevna/js-course GitHub Wiki

:mortar_board: let | const

ES6 ( 2015 )

let

Функциональная и блочная области видимости

Ограничить область видимости переменных, объявленных с помощью директивы var, можно только "заворачиванием" их в функцию

Блочная область видимости - это ограничение области видимости в пределах фигурных скобок

var x = 5
{
    let x = 15
    console.log ( x )
}
console.log ( x )

Благодаря этому сборщик мусора освобождает память от ненужных переменных при выходе из блочной области видимости

:warning: let не создает свойств в глобальном объекте

var x = 25
let z = 15
window.x    //  25
window.z    //  undefined

Следствием блочной области видимости переменных, объявленных с помощью директивы let, является замыкание значения переменной цикла на каждой итерации блока for:

:coffee: 1

for ( let i of [ 1, 2, 3, 4, 5 ] ) {
    setTimeout ( () => console.log ( i ), 1000 * i )
}

:coffee: 2

Обратите внимание, что отсутствие явных фигурных скобок не меняет принцип поведения переменных, объявленных с помощью директивы let

var

var res = []

for ( var item of [ "alpha", "sigma", "omega" ] )
    res.push ( () => console.log ( item ) )

res[0]()  // omega
res[1]()  // omega
res[2]()  // omega

let

var res = []

for ( let item of [ "alpha", "sigma", "omega" ] )
    res.push ( () => console.log ( item ) )

res[0]()  // alpha
res[1]()  // sigma
res[2]()  // omega

Hoisting и "временная мёртвая зона"

Hoisting заключается в том, что переменные "поднимаются" от места их объявления в коде до топа их области видимости

Hoisting имеет такое же отношение к переменным, объявленным с помощью директивы let, как и к объявленным с помощью var

:warning: Однако переменные, объявленные с помощью let, будут недоступны до тех пор, пока выполнение кода не дойдёт до места фактического объявления переменной

Так появляется временная мёртвая зона

Поэтому в результате выполнения кода:

{
  console.log ( x )
  // [ временная мёртвая зона ]
  let x = 10
}

будет сгенерировано исключение:

:no_entry_sign: ReferenceError: Cannot access 'x' before initialization

Невозможно повторно объявить переменную с таким же идентификатором в той же области видимости:
function sample () {
    let figure = {
        name: "Radius",
        size: 50
    }
    console.log ( figure )
    let figure = 10
    console.log ( figure )
}
sample ()
Будет сгенерировано исключение:
⛔️ Uncaught SyntaxError: Identifier 'figure' has already been declared
Однако в цикле сработает, потому что явно присутствует блок {...}
let sample = { a: 'img', b: 'div', c: 'p' }
for ( let prop in sample ) {
    let elem = document.body.appendChild ( 
        document.createElement ( sample [ prop ] )
    )
    console.log ( elem )
}

const

Блочная область видимости ( как у let )
Невозможно дублирование объявления ( как у let )
В общем, все, как у let, только:
:warning: Изменить значение нельзя
const XXX = 11
XXX = 55

Будет сгенерировано исключение:

⛔️ Uncaught TypeError: Assignment to constant variable.
Обязательно при объявлении инициализировать значение
const XXX

Будет сгенерировано исключение:

⛔️ Uncaught SyntaxError: Missing initializer in const declaration
Если константа является объектом, то значения ее свойств могут быть изменены:
const USER = {
    login: "admin",
    role: "admin",
    status: "active",
    rights: [ "read", "write", "delete" ]
}

USER.login = "student"
USER.role = "user"
USER.rights = [ "read" ]
Аналогично с массивами:
const RIGHTS = [ "read", "write", "delete" ]
RIGHTS [ 1 ] = null
RIGHTS [ 2 ] = null

:briefcase: Упражнения