您的位置:首页 > Web前端 > JavaScript

javascript作用链进一步详解

2016-11-09 11:40 148 查看
javascript中作用链的建立详解为定义阶段和执行阶段,定义阶段也称为预编译阶段,在本人博客前文中有对预编译阶段和执行阶段的详解。

1,函数定义的时候,都会创建一个[[scope]]属性,通这个对象对应的是一个对象的列表,列表中的对象仅能javascript内部访问,没法通过语法访问。

  (scope也就是作用域的意思。)

  我们定义一全局函数A,那么A函数就创建了一个A的[[scope]]属性。此时,[[scope]]里面只包含了全局对象【Global Object】。

  而如果, 我们在A的内部定义一个B函数,那B函数同样会创建一个[[scope]]属性,B的[[scope]]属性包含了两个对象,一个是A的活动对象Activation Object、一个是全局对象,A的活动对象在前面,全局对象排在后面。

  简而言之,一个函数的[Scope]属性中对象列表的顺序是上一层函数的Activation Object对象,然后是上上层的,一直到最外层的全局对象。

下面是示例代码:A只有一个scope,B有两个scope

// 外部函数

function A(){

var somevar;

// 内部函数

function B(){

var somevar;

}

}

2执行期

  当函数被执行的时候,就是进入这个函数的执行环境,首先会创一个它自己的活动对象【Activation Object】(这个对象中包含了this、参数(arguments)、局部变量(包括命名的参数)的定义和一个变量对象的作用域链[[scope chain]],然后,把这个执行环境的[scope]按顺序复制到[[scope chain]]里,最后把这个活动对象推入到[[scope chain]]的顶部。这样[[scope chain]]就是一个有序的栈,这样保了对执行环境有权访问的所有变量和对象的有序访问。

  以下通过一段程序详细讲解

// 第一步页面载入创全局执行环境global executing context和全局活动象

// 定义全局[[scope]],只含有Window对象

// 扫描全局的定义变量及函数对象:color【undefined】、changecolor【FD创建changecolor的[[scope]],此时里面只含有全局活动对象】,加入到window中,所以全局变量和全局函数对象都是做为window的属性定义的。

// 程序已经定义好所以在此执行环境内任何位置都可以执行changecolor(),color也已经被定义,但是它的值是undefined

// 第二步color赋值”blue”

var color = “blue”;

// 它是不需要赋值的,它就是引用本身

function changecolor() {

// 第四步进入changecolor的执行环境

// 复制changecolor的[[scope]]到scope chain

// 创建活动对象,扫描定义变量和定义函数,anothercolor【undefined】和swapcolors【FD创建swapcolors的[[scope]]加入changecolor的活动对象和全局活动对象】加入到活动对象,活动对象中同时还要加入arguments和this

// 活动对象推入scope chain 顶端

// 程序已经定义好所以在此执行环境内任何位置都可以执行swapcolors(),anothercolor也已经被定义好,但它的值是undefined

// 第五anothercolor赋值”red”

var anothercolor = “red”;

// 它是不需要赋值的,它就是引用本身

function swapcolors() {

// 第七步进入swapcolors的执行环境,创建它的活动对象

// 复制swapcolors的[[scope]]到scope chain

// 扫描定义变量和定义函数对象,活动对象中加入变量tempcolor【undefined】以及arguments和this

// 活动对象推入scope chain 顶端

// 第八步tempcolor赋值anothercolor,anothercolor和color会沿着scope chain被查到,并继续往下执行

var tempcolor = anothercolor;

anothercolor = color;

color = tempcolor;

}

// 第六步执行swapcolors,进入其执行环境

swapcolors();

}

// 第三步执行changecolor,进入其执行环境

changecolor();

3访问标识符:

  当执行js代码的过程中,遇到一个标识符,就会根据标识符的名称,在执行上下文(Execution Context)的作用域链中进行搜索。从作用域链的第一个对象(该函数的Activation Object对象)开始,如果没有找到,就搜索作用域链中的下一个对象,如此往复,直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象,也就是全局对象(Global Object)以后也没有找到,则会抛出一个错误,提示undefined。

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript