理解JavaScript的作用域

什么是作用域

简单来说作用域就是变量与函数的访问范围,用于规定变量和函数是否可访问。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。

全局作用域

在代码中任何地方都可以访问到的对象拥有全局作用域。

  1. 在script标签中声明的变量和函数
  2. 全局对象 window,由浏览器创建
  3. 未定义直接赋值的变量
  4. 在全局作用域声明的函数和变量会作为 window 对象的属性和方法保存

函数作用域

声明在函数内部的变量,只能在函数内部访问。

  1. 调用函数是,函数作用域被创建,函数执行完毕时将销毁函数作用域
  2. 函数作用域可以访问到全局作用域的变量,而在函数外无法访问函数内的变量
  3. 在函数作用域中访问变量和函数时,会优先查找自身作用域,如果没找到就会到函数上一级作用域查找,一直到全局作用域。

执行上下文

在全局代码执行之前或创建一个上下文对象 GO(作用域)。
在函数代码执行之前会创建一个上下文内部对象 AO(作用域)。这个内部对象是预编译时创建的。

关于 GO和AO可以前往JavaScript-预编译查看

作用域链

1
var x = 1;
2
var y = 2;
3
function fn(){
4
    var y = 0;
5
    function f1(){
6
        function f2(){
7
            console.log(x);
8
        }
9
        f2()
10
        console.log(y);
11
    }
12
    f1()
13
}
14
fn()
1
GO : {
2
    x : 1,
3
    y : 2,
4
    fn : function fn(){}  // fn() 调用时产生 AO
5
    // => AO : {
6
        y : 0,
7
        f1 : function f1(){}  // f1() 调用时产生 AO  // 0
8
        // => Ao : {
9
            f2 : function f2(){}   // 1
10
        }
11
    }
12
}

当在内部函数中,需要访问一个变量的时候,首先会访问函数本身的变量对象,是否有这个变量,如果没有,那么会继续沿作用域链往上查找,直到全局作用域。如果在某个变量对象中找到则使用该变量对象中的变量值。这个查找过程就是依靠作用域链来的。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!