JavaScript作用域

48 阅读2分钟

作用域

在es6之前JavaScript作用域分两种:全局作用域与函数作用域。作用域可用于隔离变量,在不同的作用域下使用同名变量并不会冲突。

作用域与执行上下文

作用域与执行上下文的区别:

  1. 创建的时间:
  • 全局作用域最开始就确定了,函数作用域在函数定义时确定;
  • 全局执行上下文是在全局作用域确定好之后,代码执行之前确定。函数执行上下文是在调用函数时,执行函数之前确定;
  1. 静态与动态
  • 作用域一经确定就一直存在并不再更改。
  • 函数执行上下文随着每次函数的调用都会被创建,随着函数调用结束会自动释放。

联系:

执行上下文可以说是属于作用域的一部分。

作用域链

作用域链由多个作用域组成,在访问一个变量时先在自身的作用域查找,如果没有找到就进入上一级作用域查找,以此类推直到全局作用域。(是一个由内而外的查找过程)

    var a = 1;
        function fn1(){
            var b = 2;
            function fn2(){
                var c = 3;
                function fn3(){
                    var a = 100;
                    //先在自身找到a = 100
                    console.log(a,b,c); // 100,2,3
                }
                fn3();
            }
            fn2();
        } 
        fn1();

练习

//case 1
var obj = {
    fn2: function () {
      console.log(fn2)
    }
  }
  obj.fn2()  //报错
//case 2
var obj = {
  fn2: function () {
    console.log(this.fn2)
  }
}
obj.fn2()   //输出function fn2

对于case1,运行obj.fn2() 时先在函数内部找,没找到则根据作用域链跳到全局作用域找也没有fn2,只有obj这个对象,因此报错。

对于case2,运行obj.fn2() 时先在函数内部找this.fn2即obj.fn2,没找到则根据作用域链跳到全局作用域找,可以找到obj对象然后返回obj.fn2。(也就是说在全局作用域下对象内部的属性并不能直接被看到,需要通过对象去查找)