JavaScript变量提升和函数提升
变量提升
解析器会先解析代码,然后把声明的变量的声明提升到最前,这就叫做变量提升。
定义其实包含了-> 声明 + 赋值
1 | var web = 'https://blog.farmer233.top'; |
使用 var
声明代码会被提升到前面
1 | console.log(a); //undefined |
下面是 if(false)
中定义的var也会发生变量提升,注释掉if 结果会不同
1 | var web = "https://blog.farmer233.top"; |
使用 var
定义的代码,声明会被提升到前面,赋值还在原位置
1 | console.log(blog); |
小结
- 变量提升就是代码在预解析的时候将变量的声明提到程序的开头
- 通俗的讲就是将代码块内的变量都在开头先声明。
变量提升会导致很多莫名其妙的bug,那么该如何避免变量提升?
- 为了解决这个问题,JavaScript后来推出了let和const
- 使用严格模式
TDZ
TDZ 又称暂时性死区,指变量在作用域内已经存在,但必须在let/const声明后才可以使用。
TDZ可以让程序保持先声明后使用的习惯,让程序更稳定。
- 变量要先声明后使用
- 所以我们应该使用let/const来定义变量, 少用var
使用 let/const
声明的变量在声明前存在临时性死区(TDZ)使用会发生错误
1 | console.log(x); // Cannot access 'x' before initialization |
在run函数作用域中产生TDZ,不允许变量在未声明前使用。
1 | blog = "https://blog.farmer233.top"; |
下面代码b没有声明赋值不允许直接使用
1 | blog = "https://blog.farmer233.top"; |
总结
- 多使用JavaScript的严格模式
- 由于JavaScript的历史遗留原因,很多老问题都被新版本修复了,因此我们应多使用新版本的工具。
栗子
可能我上面的表达不太清楚,这几天在群里吹水解答沙雕群友的时候写了点小栗子也顺便贴上来吧。(随便写写.)
欢迎随便看看。
1 | // 变量提升是因为变量的定义会被浏览器先预览一次 |
1 | // 和上面同理 |
1 | // 上面讲的都是顺序程序结构,那如果变量是在代码块内定义的会怎么样? 其实一样会提升 |
1 | // 再探究一下 |