作用域
- 作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问。
- 作用域控制着变量和函数的可见性和生命周期。
- 作用域分为:局部作用域 || 全局作用域
一.局部作用域
- 局部作用域分为函数作用域和块作用域。
为什么新增块级作用域?
- 内层变量可能会覆盖外层变量 ==> var
- 用来计数的i变量可能会泄漏为全局变量 ==> var
1.函数作用域
- 在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
- 函数的形参也可以看做是函数内部的局部变量
2.块级作用域
- 在 JavaScript 中使用 { } 包裹的代码称为代码块,代码块内部声明的变量外部将有可能无法被访问。
- let/const 声明会产生块作用域,var 不会产生块作用域
- 不同代码块之间的变量无法互相访问。
二、全局作用域
<script>标签 和.js文件 的【最外层】 就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。- 全局作用域中声明的变量,任何其它作用域都可以被访问。
- 为 window 对象动态添加的属性默认也是全局的,不推荐!
- 尽可能少的声明全局变量,防止全局变量被污染。
- 伴随着页面的生命周期,关闭页面不能访问
var || let || const
区别:
- var 声明的范围是函数作用域,let 和 const 声明的范围是块作用域
- var 声明的变量会被提升到函数作用域的顶部,let 和 const 声明的变量不存在提升,且具有暂时性死区特征
- var 允许在同一个作用域中重复声明同一个变量,let 和 const 不允许
- 在全局作用域中使用 var 声明的变量会成为 window 对象的属性,let 和 const 声明的变量则不会
- const 的行为与 let 基本相同,唯一 一个重要的区别是,使用 const 声明的变量必须进行初始化,且不能被修改
作用域链
- 嵌套关系的作用域串联起来形成了作用域链
- 作用:作用域链本质上是底层的变量查找机制(就近原则)
- 在函数被执行时,会优先查找当前函数作用域中查找变量
- 如果当前作用域查找不到则会逐级向上查找父级作用域直到全局作用域
- 子作用域能够访问父作用域,父级作用域无法访问子级作用域
- 如果都没有,Error,变量没有定义过