Идея «подъема» - это плохой способ понять, что происходит. Другими словами, по-моему, «подъем» - плохое объяснение подъема.
Что действительно происходит, это не «подъем».Что действительно происходит, так это то, что javascript выполняет код в два этапа: фазу компиляции и фазу eval. Сообщество javascript называет симптом этого «подъема», но большинство людей не понимают, почему подъемные тали, потому что они считают, что у переводчиков javascript есть такая функция, называемая «подъем» (они этого не делают).
Что на самом деле происходит, проще объяснить, чем идея подъема. Правила:
Javascript всегда анализирует код сверху вниз. Он никогда не меняет код (он никогда не поднимается).
Существует два этапа исполнения: компиляция и оценка.
Все декларации обрабатываются на этапе компиляции, никакие выражения не будут оцениваться на этапе компиляции (потому что «оценка» выполняется на этапе оценки).
Все выражения и все, что необходимо оценить, обрабатываются на этапе оценки.
Помните правило 1, все синтаксические разборки выполняются сверху вниз, и нет никакого возврата, нет подъема.
Давайте вашему примеру и попытаться понять его, держа в фазе компиляции и оценки ум в JavaScript:
var myName = "Richard"; // Variable assignment (initialization)
function myName() {
console.log ("Rich");
}
console.log(typeof myName); // string
В фазе компиляции, интерпретатор видит, что вы объявить переменную. Он выделяет область памяти для этой переменной и присваивает ей значение undefined
.
В фазе усложнения интерпретатор видит, что вы объявляете функцию. Он также отмечает, что имя функции затеняет имя переменной. Поэтому он создает функцию «myName» (это означает, что в этот момент переменная myName
указывает на функцию).
Фаза завершения компиляции. Теперь мы вводим этап оценки.
На этапе оценки интерпретатор видит, что вы назначаете строку myName
.
Невозможно оценить, когда мы достигаем объявления функции, потому что декларации обрабатываются на этапе компиляции.
На этапе оценки интерпретатор видит, что вы используете consoleof. myName
. Поскольку последнее, что ему присвоено, это строка, в которой он печатает «string».
Обратите внимание, что если вы удалите задание строки, то myName
будет TypeOf «функция». Это потому, что в этом случае последнее, что ему присвоено, является объявленной функцией.
Смотрите этот родственный вопрос для других тонкостей, вызванных двумя фазами выполнения: JavaScript function declaration and evaluation order
Вы переходите от объявления функции к функции выражения в вашем примере и, к сожалению, они обрабатываются по-разному JavaScript: пока файл сканируется для деклараций функций при загрузке, выражения функций и их назначение разрешаются во время выполнения. Поэтому ваш пример, к сожалению, что-то объясняет, но не то, что было задано. –
@GoloRoden - Я объяснил, почему тип переменной 'myName' является' string', а не 'function', затем я сделал пример, где тип переменной будет' function' ;-) –