1.作用域
作用域就是变量起作用的范围。在一定空间内,可以对数据进行读写操作,这个空间就是数据的作用域。
1.1全局作用域(全局变量)
在函数外部声明,页面任何地方都可以使用
1.2局部作用(局部变量)
在函数内部声明,只能在函数内部使用
1.3块级作用域
在大括号里面声明的变量(分支和循环),只能在大括号内部使用
1.4作用域示例
<script>
//◆全局变量: 全局作用域
let num = 10
function fn() {
//◆局部变量: 局部作用域(函数内部作用域)
let age = 30
console.log(age)
}
fn()
for (let i = 1; i <= 10; i++) {
//◆块级变量:块级作用域(只能在大括号内部使用)
console.log(i)
}
</script>
***注意:函数的形参相当于在函数内部声明变量,属于局部变量
1.5块级作用域、函数作用域、词法作用域的区别
◆块级作用域与函数作用域描述的是,什么东西可以划分为变量的作用域
◆词法作用域描述的是,变量的查找规则
◆块级作用域 包含 函数作用域
◆词法作用域与块级作用域和函数作用域之间没有任何交集,他们从两个角度描述了作用域的规则
◆ES6之前采用的是函数作用域+词法作用域,ES6采用的是块级作用域+词法作用域
2.作用域链
默认情况下,js 代码处于全局作用域(0级),当我们声明一个函数的时候,就会开辟一个局部作用域(1级)。 函数里面也可以声明函数,就会又形成局部作用域(2级),以此类推就会形成作用域链。
变量在作用域链中的访问规则:就近原则
当你在某个作用域访问变量的时候,会先看当前作用域有没有声明。如果有,则访问当前作用域的变量;如果没有就找上级,上级也没有就继续往上,直到作用域的最顶端(0级);如果 0级 也没有,则程序会报错, xxx is not defined
<script>
//全局作用域(0级)
let num = 10
function fn() {
//局部作用域(1级)
let num = 20
console.log('1级作用域' + num)//20
function fn1() {
//局部作用域((2级)
let num = 30
console.log('2级作用域' + num)//30
}
fn1()
}
fn()
console.log('0级作用域' + num)//10
</script>
3.延长作用域链
执行环境的类型只有两种,全局和局部(函数),但是有些语句可以在作用域的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。简而言之,执行以下两个语句时,作用域链都会得到加强
- try-catch 语句的catch 块;会创建一个新的变量对象,包含的是被抛出的错误对象的声明
- with 语句,会将指定的对象添加到作用域链中