日期:2014-05-16 浏览次数:20396 次
?
Javascript执行时的准备工作:
当JS引擎进入一个执行环境,准备执行该区域的代码时,如下工作已经完成:(1) 变量的实例化,(2) 作用域链的创建和初始化,(3) this指针所指向的目标对象的确定。
?
1、执行环境(Execution Contexts)
一段可执行的JS代码即为一个执行环境,分为三类:
1.1 全局代码;全局代码是不包含任何函数体的代码(可以有函数调用);
1.2 Eval代码;eval是JS中的一个内置函数,eval的参数即全局代码;
1.3 函数代码;函数代码是函数体中的一部分代码,这部分代码不嵌套包括任何函数体代码。注意new Function(argList)最后一个参数也是当作函数代码处理。
?
?
2、变量实例化(Variable Instantiation?)
?
JS的每个执行环境(也叫执行上下文)都关联到一个变量对象(variable object)。变量实例化将做以下事情:
2.1 ?如果该执行环境是函数代码的执行环境,每一个形参作为属性添加到变量对象中,属性名为形参名,值是调用该函数时所提供的实参的值。如果实参少于形参,则多出的形参赋值为undefined。如果有形参中有两个或者两个以上的参数的名字相同,则最后一个形参的值是变量对象中该形参的值,即使最后一个形参为undefined。
?
?
2.2 ?把函数定义式定义的函数(不是函数表达式定义的函数)作为属性添加到变量对象中。属性名为函数名,值为通过new Function(参数列表) 创建的一个函数对象,该对象的属性由代码决定(执行的时候确定)。如果变量对象中已经存在该名字的属性,则用新的值和属性替换旧的值和属性。
?? 如果执行环境是函数代码,必须先初始化函数的形参列表,然后再处理该步骤。
?
?
2.3 把通过关键字var定义的变量(该变量也可以是源码某个语句块中定义的,如:for语句循环体中定义的)作为属性添加到变量对象中,属性名为变量名,值为undefined,值的属性由代码确定(执行的时候确定);如果该变量名和函数定义或者形参重合,则不摈弃变量对象中该属性的已有属性。
?? ? ?语义上,必须先初始化函数形参列表和函数定义,再处理该步骤。
?
?
?
实验1(环境Chrome 8 ):
<script language="javascript"> var fun; function fun(a, b, a){ alert(a); } fun(1, 2, 3);//弹出:3 fun(1, 2);//弹出:undefined var fun = 'not function'; fun(1);//出错 </script>
?
?
3、作用域链(Scope Chain)和变量识别(Identifier Resolution)
每个执行环境都与一个作用域链关联。作用域链是一个对象列表,主要用于变量识别(可以理解为它由赋值后的变量对象以链表的形式构成)。系统按照以下步骤来计算一个变量 v的值:
4、全局变量(global object)
?