Что такое подъем?

Подъем - это стандартное поведение JavaScript для перемещения переменных и объявлений функций в верхнюю часть области видимости. Объем может варьироваться в зависимости от того, где он заявлен. Это может быть уровень страницы, уровень функции или уровень блока. Поднимаются только объявления, но не инициализации.

Повышение уровня страницы (оконного / глобального):

По умолчанию все переменные, объявленные на уровне страницы, будут подняты автоматически. Например, из приведенного ниже кода будет поднята переменная currentScope.

console.log(currentScope); //prints undefined and hoisted
var currentScope = "window";

Подъем на уровне блока:

Переменные, объявленные внутри блока, будут подняты как на его лексическом уровне, так и на уровне блока.

console.log(blockscope);// hoisted, prints undefined
{
    console.log(blockscope);// hoisted, prints undefined 
    var blockscope = "True";
}

Переменные, объявленные внутри цикла for и while, будут подняты как на уровне блока цикла, так и на его лексическом уровне.

console.log(isWhileLoop);  //hoisted
while (false) {
    console.log(isWhileLoop); //hoisted, prints undefined
    var isWhileLoop = "Yes";    
}
console.log(isForLoop);  //hoisted
for(var i=0;i<5;i++) {
    console.log(isForLoop); //hoisted, prints undefined
    var isForLoop = "Yes";    
}

Переменные, объявленные внутри условных блоков, будут подняты как на уровне блока, так и на его лексическом уровне.

console.log(isFalse); //hoisted, prints "Yes"
if(false){
    console.log(isFalse); //hoisted, prints "Yes"
    var isFalse = "Yes";
}
console.log(isFoundDay); //hoisted
console.log(isNotMatching); //hoisted
var day = 3;
switch(day){    
    case 1:{        
        break;
    }
    case 2:{
        var isNotMatching = "Yes";
        break;
    }
    case 3:{
        console.log(isFoundDay); //hoisted
        var isFoundDay = true;
        break;
    }
}

Подъемные функции и их переменные.

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

console.log(sayHelloFunction); //will throw a reference error, var sayHelloFunction is not defined
console.log(typeof sayHello); //prints function, and it can be called too
console.log(sayHello()); //will execute the function
function sayHello(){
    console.log(sayHelloFunction); //hoisted
    var sayHelloFunction = true;
}

console.log(expFunction); //declaration hoisted, prints undefined
console.log(expFunction());//Throws error, expFunction is not a function
var expFunction = function(){ 
    console.log(isExpFunction); //hoisted, prints undefined
    var isExpFunction = true;
}

ES6 let и const подъем:

ES6 let и const не поднимаются, выдаст ошибку ссылки, если объявление не найдено в вызывающей области.

console.log(isES6); //not hoisted, will throw ReferenceError
let isES6 = true;
console.log(techStack); //not hoisted, will throw ReferenceError
const techStack = ["JS","HTML", "CSS"];