В этой статье мы собираемся обсудить подъем в JavaScript.

Поднятие – это процесс, происходящий во время создания контекста выполнения, который перемещает объявления переменных и функций наверх контекста. Начнем с примера:

hello();
function hello(){
    return "Hello World";
}

Если вы знакомы с JavaScript, вы знаете, что это не приведет к ошибке. Когда во время создания глобального контекста выполнения происходит то, что механизм перемещает объявление переменной (в данном случае функция «привет») в контекст, когда он видит ключевое слово «функция». Это также означает, что перед выполнением код будет выглядеть примерно так:

function hello(){
    return "Hello World";
}
hello();

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

console.log(text)
var text = "Hello World!"

Допустим, у меня есть фрагмент кода, который пытается вывести переменную text до того, как она будет объявлена ​​и определена. Что он распечатает?

undefined

Неопределенный. Когда движок увидит «var», он будет знать, что нужно оставить кусок памяти для этой переменной, но он не знает, какое значение было присвоено этой переменной. Поэтому, когда объявление переменной поднимается, по умолчанию этой переменной присваивается значение «undefined». По этой причине ошибка не выдавалась, а вместо этого выводилось «undefined».

Вы также видели такой способ определения функции:

hello();
var hello = function(){
    return "Hello World";
}

Это функциональное выражение. Что, если мы сделаем это? Сможем ли мы правильно распечатать «Hello World»?

VM592:1 Uncaught TypeError: hello is not a function
    at <anonymous>:1:1

Хм… хорошо, значит, движок не знает, что это функция. Помнить? Когда движок увидит «var», он переместит объявление «hello» вверх и выдаст неопределенное значение по умолчанию. Если вы попытаетесь вызвать его, он скажет вам, что это не функция. Давайте распечатаем, что такое hello, прежде чем назначать ему эту функцию.

console.log(hello);
var hello = function(){
    return "Hello World";
}
undefined

Только что мы упомянули, что при создании контекста выполнения объявление переменных поднимается. Давайте попробуем это:

function hello(){
    console.log("1: " + text)
    var text = "Hello World"
    console.log("2: " + text)
}
hello()

Что мы можем ожидать здесь?

1: undefined
2: Hello World

Хорошо, это согласуется с тем, что мы только что обсудили. Давайте присвоим значение «тексту» в глобальной области видимости.

var text = "Am I printed?"
function hello(){
    console.log("1: " + text)
    var text = "Hello World"
    console.log("2: " + text)
}
hello()

Опять же, что вы ожидаете, что он распечатает?

1: undefined
2: Hello World

Тем не менее, 1: не определено. Когда вызывается hello(), создается новый контекст выполнения, и переменная text поднимается наверх этого контекста hello(), поэтому она не знает о назначенном значении из глобального контекста выполнения.

Давайте попробуем еще одну вещь, мы удалим объявление переменной внутри hello():

var text = "Am I printed?"
function hello(){
    console.log("1: " + text)
}
hello()
1: Am I printed?

Да, вы напечатаны. Цепочка прицелов, верно? (Область действия JavaScript)

Как вы думаете, все это вызовет путаницу, когда мы пишем код JavaScript?

Чтобы сделать наш код более предсказуемым, мы можем использовать «let» и «const» в ES6. Их не поднимают.

hello();
const hello = function(){
    return "Hello World";
}
Uncaught ReferenceError: hello is not defined
    at <anonymous>:1:1

Да, так лучше. Когда вы только начинаете изучать JavaScript, могут возникнуть неожиданные ситуации (например, приведение типов). Однако понимание этих концепций определенно сделает вас лучшим разработчиком JavaScript.

Поскольку мы упомянули «let» и «const», я также хотел бы добавить еще одно, касающееся области действия блока и области действия функции. Когда мы используем другие языки, мы ожидаем, что это вызовет ошибку (здесь мы используем groovy в качестве примера):

if(someCondition)
{
    def someVar = "Can you see me? "
}
def newVar = someVar + "I cannot see you."

Это связано с тем, что переменная определена в «области блока». Что, если мы сделаем это в JavaScript?

var someCondition = true
if(someCondition)
{
    var hello = "Hello "
}
var helloWorld = hello + "World"
console.log(helloWorld)
Hello World

В этом случае для JavaScript ошибка не будет выдана. Это связано с тем, что «var» ограничен только функцией и модулем. Если вы сделаете это в функции, она выдаст ошибку.

function someFunction()
{
    var hello = "Hello "
}
var helloWorld = hello + "World"
console.log(helloWorld)
VM1525:6 Uncaught ReferenceError: hello is not defined
    at <anonymous>:6:18

Что, если мы также хотим иметь блочную область для {}?

Используйте «let» и «const».

let someCondition = true
if(someCondition)
{
    let hello = "Hello "
}
let helloWorld = hello + "World"
console.log(helloWorld)
VM1566:8 Uncaught ReferenceError: hello is not defined
    at <anonymous>:8:18

Вот и все для этой статьи, надеюсь, вам понравилось!

Следуйте за мной, если вы хотите видеть больше контента, связанного с веб-разработкой или разработкой программного обеспечения. Ваше здоровье!

Повышение уровня кодирования

Спасибо, что являетесь частью нашего сообщества! Больше контента в публикации Level Up Coding.
Подписывайтесь: Twitter, LinkedIn, Информационный бюллетень
Level Up меняет рекрутинг в сфере технологий ➡️ Присоединяйтесь к нашему коллективу талантов