在JavaScript中,if 语句是/有 块级作用域吗?

0 前言:本菜鸟在学习《你不知道的JavaScrip》一书中,发现如下代码:

foo(); // "b"
var a = true;
if (a) {
function foo() { console.log("a"); }
}
else {
function foo() { console.log("b"); }
}

书中给出的代码结果即为 `// 'b'`。


测试1: 然而我自己测试发现上述代码直接报错:`TypeError: foo is not a function`

在node环境(v14.19.1)和 浏览器环境(chrome 107.0.5304.89(正式版本) (64 位))都是 上述错误。


测试2:当我们把 foo() 放到代码末尾时, 打印的是 a。

var a = true;
if (a) {
  function foo() { console.log("a"); }
}
else {
  function foo() { console.log("b"); }
}

foo(); // "a"

测试3 :(函数声明、和 函数表达式的不同)

 

foo1()
function foo1() {// 声明式函数,无论foo1() 放在哪,都正常执行
  console.log('foo1'); //foo1
}
foo1()

 

foo1() // 执行语法放在函数表达式前面,报错:TypeError: foo1 is not a function

var foo1 = function () { //函数表达式
  console.log('foo1');
}

foo1() // 执行语法放在函数表达式后面,代码正常执行,打印:'foo1'

1. 据此,以下为本菜鸟的分析,如有不对,欢迎大神指正:

分析1:(据书给出的结果)

a 假如书中给出的代码运行正常且 foo() 打印的指为 `// 'b'`,

b1 那么说明 if 语句没有自己块级作用域,上述代码整个即为全局作用域,且第二个 foo 函数声明覆盖了第二个 foo 函数声明。

b2 如果 if 和 else 两个 {} 块级作用域是指未一个块级作用域,也会出现后者覆盖前者。但是仍旧处于块级作用域中,不会泄漏到全局。foo() 仍旧会报错。

c 因此,假设数中结果成立,那么说明 if 和 else 中的两个 foo 函数声明都会在全局作用域中,且 后者对前者覆盖了,所以最后结果打印了 b;


分析2:(根据 书给出的结果和测试1的结果)

a 在本菜鸟的测试1中,上述代码运行结果是    `TypeError: foo is not a function`

b 因为错误结果是 TypeError 而不是 ReferenceError,说明引擎编译时发生了LHS错误而不是RHS错误。即函数 foo() 声明被提升了,作用找到了foo(),但是在赋值时即LHS时发生了错误。

c 那这是否说明 if 语句没有块级作用域。但是如果没有块级作用域,那么结果应该同书中所描述的,而不是报错。

d 假如有块级作用域,那么 if 语句块级内的函数声明不应该不会泄漏到全局吗?那么错误内容应该是 ReferenceError 啊! 此时的 if 语句更像是半个块级作用域,它把`声明式函数` 的行为模式(函数在作用域内的提升) 变成了 `函数表达式`?

e 脑子一片混乱,期待大神解答。


分析3:(加上测试2 的结果)

a  重新理了一下思路,如果按照分析2 - d 的结论接着测试。

b  将 foo() 放在代码末尾,发现此时语句运行成功。且打印结果是 代码所预期的且可以被判断语句控制时的结果('a')。

c 此时 if 语句的作用域似乎也可以验证分析 2 得出的结论,“半个块级作用域,其将`函数声明`的行为模式变为`函数表达式`“。

2.结尾

a 书中后续也写了这么一句话:“但是需要注意这个行为并不可靠,在 JavaScript 未来的版本中有可能发生改变,因此应该 尽可能避免在块内部声明函数。”

b 有大佬帮本菜鸟分析一波我这思考思路错在哪了吗?或者说JavaScript本身已经改变了什么?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值