美文网首页
JavaScript作用域

JavaScript作用域

作者: kim_jin | 来源:发表于2018-09-28 10:05 被阅读0次

作用域链相关概念

执行环境
执行函数定义了变量或是函数有权万文的其它数据,决定了他们各自的行为。每个执行环境都有和它关联的变量对象和一个作用域链。在环境中定义的所有的变量和函数都保存在活动对象中,现在我们将环境划分为2种:全局执行环境、函数执行环境。
全局执行环境:是最外围的执行环境,它的变量对象对应的是全局活动对象,全局执行环境在应用程序退出(网页关闭)的时候才会被销毁。
函数执行环境:每一个函数都有自己的执行环境,当我们去执行一个函数的时候,函数环境就会被推入到一个环境栈中,当这个函数执行完毕的时候,环境栈会将这个函数弹出,然后将控制权返回给之前的执行环境。函数的执行环境变量对象就是函数的活动对象。

作用域链
每一个执行环境,都会创建一个和它关联的作用域链。每一个执行环境的作用域前端,始终都是改执行环境的变量对象,对于全局的执行环境相当于windows对象,对于函数执行环境相当于该函数的活动对象;对于全局执行环境,已经退到最开始,没有后续的,对于函数执行环境,它的作用域后续是该函数对象的[[scope]]属性的作用域链。

函数对象
在一个函数定义的时候,就会创建一个这个函数对象的[[scope]]属性,并将[[scope]]属性指向定义它的作用域链上面。

活动对象
在一个函数对象被调用的时候,就会创建一个活动对象,首先将这个函数的每一个形参和实参,都添加为这个活动对象的属性和值;将改函数体内声明的变量和函数,也添加为该活动的属性(在刚刚进入函数的执行环境的时候,没有被赋值所以值没有被赋值,所以表现为undefined,这个是JS的提前声明机制)
然后将这个活动对象作为函数执行环境作为作用域链的最前端,并将这个函数对象的[[scope]]属性里面的作用域链接入到该函数执行环境作用域的后端。

  var scope = "global"; 
  function fn1(){
    return scope; 
  }
  function fn2(){
    return scope;
  }
fn1();
fn2();

上面的是一个举例子的函数,当fn1执行的时候,我们就会在内存中构建一个如下图的作用域链:

作用域链图表

图中为fn1执行的时候,我们会先创建一个执行环境,然后在执行环境中会引出作用域链,在作用域链上面,0指向的是自己,然后在1,2...都会向父级进行查找,直到找到window为止。在例子里面我们看到了因为调用fn1的就是window,所以1指向向了全局。而0指向的是自身。
那下面我们看一下闭包的作用域链式什么样的

function outer(){
  var scope = "outer";
  function inner(){
    return scope;
  }
  return inner;
}
var fn = outer();
fn();

具体的作用域链如图所示:


作用域链

因为闭包向外面一直有一个引用的存在,所以即使函数执行结束,也不会被销毁。

相关文章

网友评论

      本文标题:JavaScript作用域

      本文链接:https://www.haomeiwen.com/subject/tqwsoftx.html