“提升”的想法是了解正在发生的事情的不好方法。换句话说,在我看来,“吊装”是对吊装的不好解释。
真正发生的不是“吊装”。真正发生的是javascript分两个阶段执行代码:编译阶段和评估阶段。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
.
当我们到达函数声明时,没有什么要评估的,因为声明是在编译阶段处理的。
在评估阶段,解释器看到你 console.logging typeof myName
。由于分配给它的最后一个东西是一个字符串,它打印“字符串”。
请注意,如果您删除字符串分配,那么myName
将是 typeof "function"。那是因为在这种情况下,分配给它的最后一件事是声明的函数。
有关由两个执行阶段引起的其他细微差别,请参阅此相关问题:JavaScript 函数声明和评估顺序