javascript - 函数不会在 if else 语句和 for 循环中被提升?
问题描述
所以是的,这是你实际上不想做的事情,你总是想避免为不同的函数使用相同的名称 + 你不想再使用 var 来声明变量,因为这会导致很多问题,但我好奇为什么会这样!
我们知道使用关键字 var 声明的变量和函数声明在创建阶段被提升到其函数范围的顶部,让我们先看一个变量的示例:
function f(){
console.log(p) // undefined
if(true){
var p = true;
}
}
f()
由于我们在 if 块中声明了一个变量,并且由于 if 没有获得自己的执行上下文,因此我们得到了 undefined,我们声明的变量被提升到顶部,如下所示:
function f(){
// under the hood
var p = undefined;
console.log(p) // undefined
if(true){
p = true;
}
}
f()
一切都有道理,现在让我们以函数为例!
function f(){
let num = 5;
if(num < 10){
function a(){
console.log('less than 10')
}
a()
} else if(num < 20){
function a(){
console.log('less than 20')
}
a()
} else {
function a(){
console.log('something else')
}
a()
}
}
f()
这将返回“小于 10”,但为什么呢?
我预计吊装会像这样发生:
function f(){
/* HOISTING
function a(){
console.log('something else')
}
// HOISTING COMPLETED
*/
let num = 5;
if(num < 10){
a()
} else if(num < 20){
a()
} else {
a()
}
}
f()
因为我们在每个 if-else 块中都有同名的函数a,所以无论我们在 num 变量中输入什么值,都应该使用最后一个函数!
我们知道如果我们有多个同名函数,则使用最后一个,因为这是最后一个被提升的函数,如本例所示:
function f(){
b() // false
function b(){
console.log(true);
}
function b(){
console.log(false);
}
}
f()
那么 if-else 是怎么回事?
for循环也是如此。for 循环没有自己的执行上下文,因此使用 var 关键字和函数声明声明的变量也应该提升到其主函数范围的顶部,不是吗?但是这段代码不起作用:
function f(){
ff();
for (let i=0; i<1; i++){
function ff(){
console.log(true);
}
}
}
f();
我希望 for 循环“ff”中的函数被提升到我们的主 f 函数的顶部,但它没有!
(再一次,我知道定义两个同名的函数,或者在声明之前调用函数,使用 var 关键字等是一种糟糕的做法。这些是你一直想要避免的,但我正在深入尝试清除此类问题)
解决方案
变量似乎在 for 循环中被提升,因此为什么我们在第 3 行未定义!
f();
function f(){
console.log(v); // undefined
for (let i=0; i<1; i++){
var v = true;
}
}
...但功能不会!
f();
function f(){
v(); **error: Uncaught ReferenceError: v is not defined**
for (let i=0; i<1; i++){
function v(){
console.log('hoisting wont happen')
}
}
}
推荐阅读
- html - 字体在不同浏览器中看起来不同
- javascript - 在版本 6.1.8 中单击按钮时,Revolution 滑块如何再次启动(播放)?
- powershell - 将结果输出到文件
- jestjs - 开玩笑无法读取 null 的属性“createEvent”
- terminal - 终端卡住加载 GatsbyJS “Hello-World” 入门网站
- networking - az login 返回错误“无法建立新连接:[Errno -3] 名称解析临时失败”
- python - 检查DataFrame中的第n个值是否等于字符串中的第n个字符
- angular - 角度9一一显示对象的值数组
- elasticsearch - 无法在不将数据转发到聚合器的情况下将数据转发到弹性搜索
- java - 测试与多个 LDAP 服务器的连接时出错