js中函数的创建和调用都发生了什么?执行环境,函数作用域链,变量对象

2017-11-26 23:36:52 4,310 views

1函数的创建和调用都发生了什么?

 

1.1函数的创建

1.1.1执行环境

执行环境定义了变量或函数有权访问其他的数据。

1.1.2变量对象

每个执行环境都有一个与之关联的变量对象,通过作用域链来关联,这个变量对象中保存着执行环境中定义的所有变量和函数。我们编写的代码是无法访问到的,但解析器在处理数据时会在后台使用它。        -------  关于执行环境和变量对象的关系可见下面的图片
1.1.3作用域链:
作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象最初只包含一个变量,即函数内部的arguments对象。作用域链的下一个变量对象来自包含环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象
创建一个函数compare,

function compare(value1,value2){
if(value1<value2){
return -1;}
else if(value1>value2){
return 1;
}else{
return 0;
}
}
var result=compare(5,10);

 
首先会创建一个包含全局变量对象的作用域链,这个作用域链被保存在函数内部的[[Scope]]属性中

1.2函数调用时

会为函数compare创建一个执行环境,及相应的作用域链0(通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链,此后,又有一个活动对象(变量对象)被创建并被推入执行环境作用域链前端)。然后使用arguments和value1,value2来初始化函数的活动对象。
如下面为一个compare函数的执行环境和作用域链,变量对象之间的关系
函数的执行环境和作用域链的关系
 
就compare函数而言,它包含2个变量对象,一个全局变量对象和一个本地活动对象。

1.3查找变量

在函数执行过程中,为读取和写入变量的值,需要在作用域链中查找变量。这里就需要涉及到标识符查找。首先在作用域链的前端开始查找匹配的标识符,如果在局部环境中找到了标识符,搜索过程就停止,变量就绪。如果没找到,则继续沿着作用域链向上搜索。搜索过程一直追溯到全局环境的变量对象。如果在全局环境中野没有找到标识符,则意味着变量未声明。返报错,ReferenceError: 变量is not defined,

1.4函数执行完毕

一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(直至浏览器关闭时才销毁)。但是闭包会保留对函数的作用域的引用。
 

2.作用域链的本质

是一个指向变量对象的指针列表,它只引用但不包含实际的变量对象。

3.作用域链的作用

保证对当前执行环境有权访问的变量或函数的有序访问

4延长作用域链

通过在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行以后被移除

4.2try-catch语句的catch块

会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明

4.3with语句

会将制定的对象添加到作用域链中

4

分享到微信朋友圈

打开微信,点击底部的“发现”,
使用“扫一扫”即可将网页分享至朋友圈。