作用域和作用域链

作用域:

作用域有两种,一种是全局作用域,对应全局变量;另一种是局部作用域,对应的是局部变量。

最外层函数定义的变量拥有全局作用域,对任何内部函数来说,都是可以访问的。

局部作用域一般只在固定的代码片段内可以访问,函数外部是访问不到的。

闭包有权访问另一个函数作用于中的变量,在闭包函数执行时,会将它的外部函数的对象添加到它的作用域中。

ES6之前没有块级作用域,JavaScript的作用域是相对函数而言的。

C++:

for(int i=0;i<5;i++){
  //i的作用范围只在这个for循环里面
}
printf("%d",&i); //error

 JavaScript:

for(var i=0;i<5;i++){
}
  console.log(i); //5

ES6增加了块级作用域,用let声明。

作用域链:

执行环境定义了变量或者函数有权访问的其他数据,决定了它们各自的行为,每个执行环境都有一个与之关联的变量对象。当代码在一个执行环境中执行时,会创建变量对象的作用域链,作用域链是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。

Tips:     

  • 标识符解析是沿着作用域链一级一级地搜索标识符的过程。
  • 内部环境可以通过作用域链访问到所有的外部环境,但是外部环境不能访问内部环境的任何变量和函数。

作用域链的示例如下:(参考JavaScript高级程序设计)

var color = "blue";
    function changeColor(){
      var anotherColor="red";
      function swapColor(){
        var tempColor=anotherColor;
        anotherColor=color;
        color=tempColor;
        //这里可以访问color, tempColor, anotherColor.
      }

      swapColor();
      //这里可以访问color和anothColor;但是不能访问tempColor。

    }

    changeColor();
    //这里只能访问color

用图的形式表示以上代码的作用域:

延长作用域链:

有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除,当执行流进入下列任何一个语句时,作用域链就会加长。

  • try-catch语句中的catch块;
  • with语句。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章