当 JavaScript 运行一个函数时,会进行两个阶段的操作:
-
预编译阶段,它会扫描整个函数代码,收集函数中的变量声明,将其存储在内存中。在这个阶段,JavaScript 引擎会将函数中的变量声明提升到函数体的顶部,并给它赋上默认值
undefined
。这个过程就是 变量提升(Hoisting)。 -
执行阶段,逐行执行函数中可执行的语句。
下面是一个变量提升的示例:
console.log(x); // undefined
var x = 1;
在预编译阶段,变量 x 被提升到函数体的顶部,当程序运行到 console.log(x) 时,由于变量 x 虽然已经被提升,但未被赋值,所以输出 undefined
。
变量提升有一个例外:用 let
或 const
声明的变量不会被提前声明。这是因为 let
和 const
声明的变量具有块级作用域。
下面是一个函数提升的示例:
hello();
function hello() {
console.log('Hello World!');
}
// 输出:Hello World!
在预编译阶段,函数 hello 被提升到函数体的顶部,因此即使在函数声明之前调用函数,也不会出现 ReferenceError。
需要注意的是,对于函数表达式,变量名的提升与函数不同,变量名不会被带到函数体的顶部。在调用函数之前,该变量名不能被访问。
下面是一个函数表达式的示例:
hello();
var hello = function() {
console.log('Hello World!');
}
// TypeError: hello is not a function
在预编译阶段,变量 hello 被提升到函数体的顶部,但此时它的值为 undefined
。当程序运行到 hello() 时,尝试调用一个未定义的变量会抛出 TypeError
异常。
综上所述,了解变量及函数的提升对于理解 JavaScript 中作用域和闭包等概念至关重要。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:了解javascript中变量及函数的提升 - Python技术站