《JavaScript高级程序设计》读书笔记4.2执行环境及作用域

执行环境和作用域的关系?
执行环境,也称执行上下文(Execution context,EC),都有与之关联的作用域(链)。每个执行环境会向上搜索作用域链进而形成一个自己的作用域。

1.执行环境及作用域

  • 执行环境(环境): 定义了变量或函数有权访问的其他数据,决定了他们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个变量对象中。

  • 全局执行环境是最外围的一个执行环境。在浏览器中,全局执行环境就是window对象。

  • 执行环境分全局执行环境(全局环境)和函数执行环境。每个函数都有自己的执行环境。

  • ECMAScript执行流机制:当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。等价于:某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。

  • 作用域链: 当代码在一个环境中执行时,会创建变量对象的一个作用域链。其用途,是保证对执行环境有权访问的变量和函数的有序访问。

  • 作用域链结构:作用域链前端,始终是当前执行的代码所在环境的变量对象,而下一个变量对象则是来自包含它的外部环境。这样,一直延续到全局执行环境。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var color="blue";
    function changeColor(){
    if(color==="blue"){
    color="red";
    }else{
    color="blue";
    }
    }
    changeColor();
    alert("Color is now"+color); //结果是red

    //函数changeColor()作用域链包含两个变量对象:
    //自己的变量对象(其中定义着arguments对象)
    //全局环境的变量对象。
  • 局部作用域中定义的变量可以在局部环境中与全局变量互换使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var color="blue";
    function changeColor(){
    var anotherColor="red";
    function swapColors(){
    var tempColor=anotherColor;
    anotherColor=color;
    color=tempColor;
    //这里可以访问color、anotherColor和tempColor
    }
    //这里可以访问color、anotherColor,不能访问tempColor
    swapColors();
    }
    //这里只能访问color
    changeColor();

作用域如下图:
阿迪
作用域链规则:执行环境之间的联系是线性、单向、有次序的。
每个环境可以向上搜索作用域链,以查询变量和函数名;但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。

2.延长作用域链

  • 怎么延长:有些语句在(其父)作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除。
  • 两个语句:
    • with语句:将指定对象添加到(其父)作用域的前端
    • try-catch语句的catch块:会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。
      1
      2
      3
      4
      5
      6
      7
      8
      function buildUrl(){
      var qs="?debug=true";
      with(location){
      var url=href+qs;
      }
      return url;
      }
      //with语句将其变量对象添加到buildUrl()作用域链前端,buildUrl()可以访问url变量了。

3.没有块级作用域

块级作用域指:类C语言中,花括号封闭的代码块都有自己的作用域(EMAScript中是执行环境),花括号内的代码执行完后变量和函数定义会被销毁。而Javascript没有块级作用域。

3.1 声明变量
  • 使用var声明的变量会自动被添加到最近的环境中。
  • 在函数内部,最接近环境是函数的局部变量
  • 在with语句中,最接近环境的函数环境。
3.2 查询标识符
  • 从作用域前端开始,逐渐向上查询,查到就停止。
  • 访问局部变量比全局变量快。
liborn wechat
欢迎您扫一扫上面的微信二维码,订阅我的公众号!