非严格模式下块内函数声明顺序为何对全局变量影响不同?
非严格模式下两段代码的执行差异解析
代码示例1(输出 "b")
if (true) { x = "b"; function x() {} } console.log(x); //b
代码示例2(输出 ƒ x() {})
if (true) { function x() {} x = "b"; } console.log(x); // ƒ x() {}
差异原因
这是非严格模式下浏览器对块级函数声明的特殊兼容处理导致的(ES5规范原本不允许在块级作用域里声明函数,浏览器为兼容旧代码做了特殊逻辑):
- 全局变量的提前绑定:不管块内代码顺序如何,浏览器都会在进入块之前,把块内的
function x(){}赋值给全局变量x。 - 块内变量的绑定逻辑:
- 示例1中,先执行
x = "b"时,还未触发块内的函数绑定,修改的是全局变量x,将其改为字符串"b";后续的function x(){}会在块内创建局部x绑定,但这个局部绑定不会覆盖已修改的全局x,最终全局x保留为"b"。 - 示例2中,先出现
function x(){}时,浏览器会在块内创建局部x绑定(和全局x指向同一个函数);后续的x = "b"修改的是这个块内局部x,块执行结束后局部绑定失效,全局变量x仍保持最初的函数引用,最终输出函数。
- 示例1中,先执行
内容的提问来源于stack exchange,提问作者Baba
相关产品推荐
相关产品推荐

