Как JS подъем работает внутри функций? - PullRequest
1 голос
/ 17 июня 2020

Может кто-нибудь объяснить мне, почему (1) возвращает 11, где (2) возвращает undefined. каково влияние функциональных блоков / объявлений на подъем?

// (1)
var boo = 11
console.log(boo) // 11
var boo = 10

// (2)
var boo = 11
function foo() {
   console.log(boo)
   var boo = 10
}
foo() // undefined

Ответы [ 4 ]

2 голосов
/ 17 июня 2020

JavaScript подъем внутри функций означает, что объявление переменных перемещается в верхнюю часть функционального блока. Когда вы вводите foo(), var boo немедленно повторно объявляется, даже если вы его не достигли (поскольку механизм JS знает, что это объявление существует внутри функции). Соответственно, причина того, что он не определен, заключается в том, что он был только объявлен, вы не присваиваете значение до следующей строки.

На самом деле, это не та ситуация, в которой вы должны оказаться, если вы объявляете переменные в соответствующей области и не повторно объявляете переменные с тем же именем, но я понимаю ваше любопытство.

Подробнее об этом можно прочитать здесь .

2 голосов
/ 17 июня 2020
Объявление

var (в отличие от let) всегда выполняется в верхней части своего блока, что означает:

var boo = 11
function foo() {
   console.log(boo)
   var boo = 10
}
foo()

равно

var boo = 11
function foo() {
   var boo // undefined
   console.log(boo)
   boo = 10 // 10
}
foo()
1 голос
/ 01 июля 2020

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

Когда вы запускаете файл javascript, создается первый глобальный контекст выполнения. Глобальный контекст выполнения дает глобальный объект, ключевое слово this и поднимает объявления var и объявления функций.

в первой части вашего вопроса:

var boo = 11
console.log(boo) // 11
var boo = 10

boo поднимается следующим образом:

var boo=undefined. 

Потому что переменные ЧАСТИЧНО поднимаются. var boo=10 не будет перезаписывать var boo=undefined. вот как это выглядит после подъема:

var boo=undefined
    boo = 11
    console.log(boo) // it is clear why 11
    var boo = 10

во второй части вашего вопроса:

var boo = 11
function foo() {
   console.log(boo)
   var boo = 10
}
foo() 

var boo в глобальном контексте частично поднят.

var boo=undefined

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

function foo() {
   var boo=undefined  
   // "boo" is partially hoisted inside  
   // "boo" is written into the variable environment of the execution context
   // "foo()" will always look into the its variable environment first
   console.log(boo)
   boo = 10
}

мы определили переменную более одного раза, но в разных областях. у нас есть var boo =11 в родительской области и var boo=10 в локальной области. это пример переменного затенения. foo () сначала будет использовать локальную переменную, поэтому локальная переменная затеняет родительское значение.

0 голосов
/ 17 июня 2020

не используйте var все время после первого раза, когда вам нужно перезаписать boo

EDIT: он не определен, потому что вы объявляете его дважды

только 2 работает нормально, если объявлено один раз а затем перезаписываем в функции

// (1)
var boo = 11
console.log(boo) // 11
 boo = 10

// (2)
var boo = 11
function foo() {
   console.log(boo)
   boo = 10
}
foo() // 11

Если вы хотите переобъявить в функции и вызвать ее, вам необходимо консоль после объявления как минимум

    // (2)
    var boo = 11
    function foo() {
       boo = 10
       console.log(boo)
    }
    foo() // 10
...