1. 作用域
目标:了解作用域对程序执行的影响及作用域链的查找机制,使用闭包函数创建隔离作用域避免变量污染。
- 作用域(scope)规定了变量能够被访问的 “范围” ,离开了这个 “范围” 变量就不能被访问。
- 作用域分为:
-
- 局部作用域
-
- 全局作用域
1.1 局部作用域
局部作用域分为函数作用域和块作用域。
1. 函数作用域:
在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
function getSum(){
// 函数内部是函数作用域 属于局部变量
const num = 10
}
console.log(num) // 此处报错,函数外部不能使用局部作用域变量
总结:
1.函数内部声明的变量,在函数外部无法被访问
2.函数的参数也是函数内部的局部变量
3.不同函数内部声明的变量无法相互访问
4.函数执行完毕后,函数内部的变量实际被清空了
2.块作用域:
在JavaScript中使用 { } 包裹的代码称为代码块,代码块内部声明的变量外部将【有可能】无法被访问。
for(let t = 1; t <= 6; t++){
// t 只能在该代码块中被访问
console.log(t) // 正常
}
// 超出了 t 的作用域
console.log(t) // 报错
1.let 声明的变量会产生块作用域,var 不会产生块作用域
2.const 声明的常量也会产生块作用域
3.不同代码块之间的变量无法相互访问
4.推荐使用 let 或 const
总结:
- 局部作用域分为哪两种?
- 函数作用域 函数内部
- 块级作用域 { } - 局部作用域声明的变量外部能使用吗?
- 不能
1.2 全局作用域
<script>标签
和 .js文件
的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。
全局作用域中声明的变量,任何其它作用域都可以被访问。
// 全局作用域
// 全局作用域下声明了 num 变量
const num = 10
function fn(){
// 函数内部可以使用全局作用域的变量
console.log(num)
}
// 此处外全局作用域
注意:
1.为 window 对象动态添加的属性默认也是全局的,不推荐!
2.函数中未使用任何关键字声明的变量为全局变量,不推荐!!!
3.尽可能少的声明全局变量,防止全局变量被污染
总结:
1.全局作用域有哪些?
- <script>
标签内部
- .js
文件
2.全局作用域声明的变量其它作用域能使用吗?
- 相当能
1.3 作用域链
思考:
1.代码有错误吗?如果没有错误,结果是几?
// 全局作用域
let a = 1
let b = 2
// 局部作用域
function f(){
let a = 1
// 局部作用域
function g(){
a = 2
console.log(a)
}
g() // 调用g
}
f() // 调用f
没有错误,结果是2
g -> f -> global
作用域链本质上是底层的变量查找机制。
- 在函数被执行时,会优先查找当前函数作用域中查找变量
- 如果当前作用域查找不到,则会依次逐级查找作用域直到全局作用域
总结:
1.嵌套关系的作用域串联起来形成了作用域链
2.相同作用域链中按着从小到大的规则查找变量
3.子作用域能够访问父作用域,父级作用域无法访问子级作用域
总结:
1.作用域链本质是什么?
- 作用域链本质上是底层的变量查找机制
2.作用域链查找的规则是什么?
- 会优先查找当前函数作用域中查找变量