[关闭]
@15152278073 2018-03-28T06:39:32.000000Z 字数 1250 阅读 663

执行环境及作用域

JS


执行环境(execution context,简称环境)是JS最为重要的一个概念.每个环境都有一个与之对应的变量对象(variable object),环境中定义的变量都保存在这个对象中.

全局环境是最外围的一个环境.在Web浏览器中,全局执行环境默认为window对象,因此,所有全局变量和函数都是作为window对象创建的.在应用程序关闭(关闭网页或浏览器)时才被销毁.

每个函数都有自己的执行环境.当执行流进入一个函数时,函数环境会推入一个环境栈中.函数执行后,栈环境会弹出,把控制权返回给之前的执行环境.

当代码在一个环境执行时,会创建变量对象的一个作用域链(scope chain).其用途是保证对执行环境有权访问的所有变量和函数的有序访问.作用域链的前端,始终都是当前执行代码所在环境的变量对象.如果环境是函数,则将其活动对象(activation object)作为变量对象.活动对象在最开始时只包含一个变量.及arguments对象(在全局环境中不存在).全局执⾏环境的变量对象始终都是作⽤域链中的最后⼀个对象.

标识符解析是沿着作⽤域链⼀级⼀级地搜索标识符的过程.搜索过程始终从作⽤域链的前端开始,然后逐级地向后回溯.直⾄找到标识符为⽌(如果找不到标识符,通常会导致错误发⽣).如下:

  1. //4.2 变量的作用域
  2. var color = "blue";
  3. function changeColor(){
  4. if(color == "blue"){
  5. color = "red"
  6. }else{
  7. color = "blue"
  8. }
  9. }
  10. changeColor()
  11. console.log(color)//red

以上例子中:changeColor()的作用域链包含两个对象:自己的变量对象(包含arguments)和全局对象.

函数参数也当作变量对待,其访问规则与执行环境的其他变量相同.

4.2.1 延长作用域

当执行流执行到下列任何一个语句时,作用域链就会延长.

4.2.2 没有块级作用域

观察以下代码,可以发现color变量的作用域延长了.

  1. if(true){
  2. var color = "blue"
  3. }
  4. console.log(color) //blue

已经经典的等例子: (推荐使用let)

  1. for (var i = 0; i < 10; i++) {
  2. //no op
  3. }
  4. console.log(i) //10

由于没有块级变量,由for创建的变量i及时循环执行结束后,也依旧存在于循环外部的执行环境中.

1.声明变量

使用var声明的变量会自动添加到最近的环境中.在函数中,就是函数的局部环境;在switch中,最接近的就是函数环境.如果变量初始化时,没有使用var声明,则该变量会自动添加到全局环境中.( 这是坑...... )

2.查询标识符

当某个环境中为了读取或引用某个标识符时,必须通过搜索来确定.搜索过程从作用域链前端开始,向上逐级查询给定名字匹配的标识符.如果在局部环境找到,搜索过程就停止,直到全局环境,即使父环境中有相同的标识符.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注