[转]js执行上下文(execution contexts)
[ 2009-06-25 17:15:17 | 作者: blueice ]
ECMAScript中可执行代码种类
全局代码(Global code):顾名思义,在全局域中,不包含在任何函数中的代码。
Eval code :内建(build-in)函数eval中的代码
Function code :函数体中的代码
函数的种类
Program functions :通过函数声明(FunctionDeclaration)、函数表达式(FunctionExpression)‘或者内建(build-in)Function对象构造的;
内部函数:如parseInt and Math.exp,(内部函数不讨论执行上下文问题)。
变量实例化(Variable Instantiation): 每一个执行上下文都关联一个variable对象,源代码中的变量、函数的声明都会添加作为variable对象的属性。如果是函数代码的话,参数也会被添加作为variable对象的属性。而且添加的顺序是添加参数-->添加函数的申明 -->添加变量的声明。后添加的同名变量会覆盖原变量。
函数的参数:如果调用者提供给函数的参数列表少于函数声明的函数列表(FormalParameterList),缺少的参数取undefined值。
函数声明(FunctionDeclaration): 对于源代码中的每个函数的声明,添加一个属性到Variable变量,属性的名称是声明中的函数Identifier,值是一个函数对象。
变量声明(VariableDeclaration):对于源代码中的每个变量的声明,添加一个属性到Variable变量,属性的名称是声明中的变量Identifier,值是undefined 。
域链(Scope Chain) : 每一个执行上下文都关联一个域链(Scope Chain),域链是用来查找计算一个Identifier值的对象的列表,在ff3下,debugger js可以看到scopeChain列表.当计算一个变量的值的时候,引擎会沿着域链来查找变量。
当进入一个执行域的时候,变量才会被创建,变量创建时被初始化成undefined。一个块(block)并不能定义一个新的域。只有程序和函数(Program and FunctionDeclaration)的声明能定义一个新的域。当引擎控制进入任何执行上下文之前,会先创建global对象。当引擎控制进入一个之星上下文,域链(Scope Chain) 会被创建初始化、变量实例化(Variable Instantiation)、this指针的值也会确定。
当我们已经懂得了以上的执行上下文的知识,就不难解释我们平常遇到的一些问题了。我昨天在陈成的博客上看到一篇js的编译和执行顺序的文章。我这里引用一下他的例子,用js的规范解释一下。
alert(t);alert('ok');t = 2;上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t不是函数参数、不是函数申明、不是变量申明,不会被实例化(参照上文3)。当代码执行到alert(t)时,执行引擎在域链(scope chain)上搜索t,就找不到t,报错。
alert(t);alert('ok');var t = 2;上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t是变量申明,被实例化,value为undefined(参照上文3.3)。所以可以执行。a();function a() {}alert('ok');上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t是函数申明,被实例化,value为function Object(参照上文3.2)。所以可以执行。a();var a = function() {};alert('ok');上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t是变量申明,被实例化,value为undefined(参照上文3.3)。所以可以执行。下面是我写的例子:function f(a,a){alert(a);};f(1);运行的结果是'undefined';上面的代码,当执行引擎进入函数f的执行上下文,变量实例化时(Variable Instantiation),由于调用着提供的参数少于声明的参数数量,所以第一个a=1,第二个a=undefined,又由于第二个a会覆盖第一个a,所以结果为undefined(参考3.1)。
评论Feed: http://www.elfnest.com/blog/feed.asp?q=comment&id=168
全局代码(Global code):顾名思义,在全局域中,不包含在任何函数中的代码。
Eval code :内建(build-in)函数eval中的代码
Function code :函数体中的代码
函数的种类
Program functions :通过函数声明(FunctionDeclaration)、函数表达式(FunctionExpression)‘或者内建(build-in)Function对象构造的;
内部函数:如parseInt and Math.exp,(内部函数不讨论执行上下文问题)。
变量实例化(Variable Instantiation): 每一个执行上下文都关联一个variable对象,源代码中的变量、函数的声明都会添加作为variable对象的属性。如果是函数代码的话,参数也会被添加作为variable对象的属性。而且添加的顺序是添加参数-->添加函数的申明 -->添加变量的声明。后添加的同名变量会覆盖原变量。
函数的参数:如果调用者提供给函数的参数列表少于函数声明的函数列表(FormalParameterList),缺少的参数取undefined值。
函数声明(FunctionDeclaration): 对于源代码中的每个函数的声明,添加一个属性到Variable变量,属性的名称是声明中的函数Identifier,值是一个函数对象。
变量声明(VariableDeclaration):对于源代码中的每个变量的声明,添加一个属性到Variable变量,属性的名称是声明中的变量Identifier,值是undefined 。
域链(Scope Chain) : 每一个执行上下文都关联一个域链(Scope Chain),域链是用来查找计算一个Identifier值的对象的列表,在ff3下,debugger js可以看到scopeChain列表.当计算一个变量的值的时候,引擎会沿着域链来查找变量。
当进入一个执行域的时候,变量才会被创建,变量创建时被初始化成undefined。一个块(block)并不能定义一个新的域。只有程序和函数(Program and FunctionDeclaration)的声明能定义一个新的域。当引擎控制进入任何执行上下文之前,会先创建global对象。当引擎控制进入一个之星上下文,域链(Scope Chain) 会被创建初始化、变量实例化(Variable Instantiation)、this指针的值也会确定。
当我们已经懂得了以上的执行上下文的知识,就不难解释我们平常遇到的一些问题了。我昨天在陈成的博客上看到一篇js的编译和执行顺序的文章。我这里引用一下他的例子,用js的规范解释一下。
alert(t);alert('ok');t = 2;上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t不是函数参数、不是函数申明、不是变量申明,不会被实例化(参照上文3)。当代码执行到alert(t)时,执行引擎在域链(scope chain)上搜索t,就找不到t,报错。
alert(t);alert('ok');var t = 2;上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t是变量申明,被实例化,value为undefined(参照上文3.3)。所以可以执行。a();function a() {}alert('ok');上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t是函数申明,被实例化,value为function Object(参照上文3.2)。所以可以执行。a();var a = function() {};alert('ok');上面的代码,当执行引擎进入执行上下文,变量实例化时(Variable Instantiation),t是变量申明,被实例化,value为undefined(参照上文3.3)。所以可以执行。下面是我写的例子:function f(a,a){alert(a);};f(1);运行的结果是'undefined';上面的代码,当执行引擎进入函数f的执行上下文,变量实例化时(Variable Instantiation),由于调用着提供的参数少于声明的参数数量,所以第一个a=1,第二个a=undefined,又由于第二个a会覆盖第一个a,所以结果为undefined(参考3.1)。
评论Feed: http://www.elfnest.com/blog/feed.asp?q=comment&id=168
浏览模式: 显示全部 |
评论: 1 |
引用: 0 | 排序 | 浏览: 503
[ 2009-06-25 17:17:32 ]
感觉特别好.






