静态作用域

什么是作用域?域是范围,字面意思就是代码起作用的范围。
JavaScript是静态作用域,也叫字面作用域,根据代码书写位置来确定变量的引用规则。例如:

var value = 1
function inner() {
    console.log(value)
}
function outer() {
    var value = 2
    inner();
}
outer(); // 打印结果为1

如果是动态作用域,就会先从inner函数内部先查找value变量,没有就查找调用inner函数的outer函数,查找到了就会打印出2

函数作用域和块级作用域

ES5只有全局作用域和函数作用域,ES6新增了块级作用域。
为什么需要引入块级作用域?因为函数作用域有它的局限,例如

var a = 1
function foo() {
    console.log(a)
    if (true) {
        var a = 5 // 定义同名变量
    }
}
foo();

这里会输出undefined,为什么呢?
调用foo函数后,会先在函数内部查找变量a,在console.log打印变量a的时候,发现了变量a的声明,但是没有赋值,赋值的动作是在打印后,所以就输出undefined
这个执行逻辑涉及到了变量提升,var a = 5这行代码分成了两部分,将代码的声明部分提升到了作用域的顶部,赋值部分放在书写代码部分。
为了避免出现变量被覆盖,所以就引入了块级作用域

var a = 1
function foo() {
    console.log(a)
    if (true) {
        let a = 5 // 用let定义同名变量
    }
}
foo();

同样的栗子,这里使用let定义块级作用域,意思就是let定义的变量a只在if这个块级起作用,这样就会打印输入1

作用域链

image.png
例如上图,变量取值的逻辑是这样,先从当前作用域查找变量的值,如果没有查找到,就从上级变量查找,这样的查找过程形成了一个链条,这个链条就是作用域链


前端茅台
14 声望0 粉丝

喜欢茅台的前端开发