二十二、变量作用域和函数声明的提升
22.1 变量作用域分为全局作用域和局部作用域
全局作用域:函数外的区域,函数外声明的变量也叫做全局变量。
- 全局变量,可以在脚本的任何位置进行调用,它随页面加载生成,页面关闭后销毁。
局部作用域:声明的函数会形成一个自己的作用域,那么在函数内声明的变量就叫做局部变量。
- 局部变量,函数被调用时创建,调用完毕后销毁
22.1.1 局部变量
局部作用域:声明的函数会形成一个自己的作用域,那么在函数内声明的变量就叫做局部变量。
- 局部变量,函数被调用时创建,调用完毕后销毁
1 | <script> |
对于JS,只有函数能够关住变量的作用域
22.1.1.1 形式参数是局部变量
形参也是局部变量,只能在函数内部使用,在外部任何地方都不能访问。
1 | <script> |
1 | <script> |
22.1.2 全局变量
全局作用域:函数外的区域,函数外声明的变量也叫做全局变量。
- 全局变量,可以在脚本的任何位置进行调用,它随页面加载生成,页面关闭后销毁。
22.1.2.1 传递作用
传递作用:在不同函数间使用全局变量可以作为信号量
,这些函数都可以改变信号量,使用新值参与计算。
1 | <script> |
22.1.2.2 通信作用
通信作用:在同一个函数使用全局变量,不会每次都清空,也是使用当前的新值参与计算。
1 | <script> |
22.2 作用域链
指的是我们变量查找的一个规律:
我们可以在不同的作用域内使用相同的标识符去命名变量。我们在使用一个变量的时候,需要找到匹配的标识符,我们有重复的,用哪一个?
如果在当前作用域有这个变量,就直接使用;
如果当前作用域没有这个变量定义,会一层一层的从本层往外依次查找。
遇到第一个就直接使用,类似于就近原则。
当遇见一个变量时,JS引擎会从其所在的作用域依次向外层查找。查找会在找到第一个匹配的标识符的时候停止。在多层嵌套的作用域中可以定义同名的标识符,发生“遮蔽效应”。
1 | <script> |
在函数内部没有使用var声明的变量,在JS运行阶段,调用函数执行到这个变量的时候,这个变量会被当作全局变量使用
注意:没有使用var声明的变量,不会进行变量的提升
建议在使用时,尽量使用var关键字声明变量,避免全局变量的污染
1 | <script> |
22.3 函数的作用域
在函数内部声明的函数,只能在函数内部声明,在函数外部任何地方都不能访问。
1 | <script> |
22.4 函数声明的提升
1 | <script> |
1 | <script> |
使用函数表达式进行提升,只提升变量名,函数的定义不能进行提升,先调用函数会报错。
1 | <script> |
总结:
在声明函数时,一般我们都使用function关键字这种,不会出错误。
并且,一般我们习惯先书写函数的调用,将声明书写在所有语句之后,便于代码读取。
变量名和函数名(function 关键字()
)相同,优先提升函数名,也就是将名字优先给函数使用。
1 | <script> |
1 | <script> |
变量的提升,预解析阶段会将var声明的变量提升到当前作用域的最顶层
局部变量函数调用时创建,调用完毕后销毁
在函数内部没有使用var声明的变量,在JS运行阶段,调用函数执行到这个变量的时候,这个变量会被当作全局变量使用
注意:没有使用var声明的变量,不会进行变量的提升
建议在使用时,尽量使用var关键字声明变量,避免全局变量的污染
1 | <script> |
1 | <script> |