认识JavaScript的作用域

         当执行JavaScript代码时,JavaScript引擎会创建一个执行上下文(Execution Context)。执行上下文(作用域)设定了代码执行时所处的环境。JavaScript引擎会在页面加载后创建一个全局的执行上下文,然后每执行一个函数时都会创建一个对应的执行上下文,最终建立一个执行上下文的堆栈,当前起作用的执行上下文在堆栈的最顶部。

         每个执行上下文都有一个与之关联的作用域链。用于解析标识符。作用域链包含一个或多个变量对象,这些对象定义了执行上下文作用域内的标识符。全局执行上下文的作用域链中只有一个变量对象,它定义了JavaScript中所有可用的全局变量和函数。当函数被创建(不是执行)时,JavaScript引擎会吧创建时执行上下文的作用域链赋值给函数的内部属性[[Scope]](内部属性不能通过JavaScript来存储,所以无法直接访问该属性)。然后,当函数被执行时,JavaScript引擎会创建一个活动对象(Activetion Object),并在初始化时给this、arguments、命名参数和该函数的所有局部变量赋值。活动对象会出现在执行上下文作用域链的顶端,紧接其后的是函数[[Scope]]属性中的对象。

        在执行代码时,JavaScript引擎通过搜索执行上下文的作用域链来解析变量和函数名这样的标识符。解析标识符的过程从作用域链的顶部开始,按照自上而下的顺序进行。看下面的代码:

function add(num1,num2){
    return num1 + num2;
}
var result = add(5,10);

        当这段代码执行时,add函数拥有一个仅包含全局变量对象的[[Scope]]属性。在执行add函数时,JavaScript引擎会创建一个新的执行上下文和一个包含this、arguments、num1和num2的活动对象,并把活动对象添加到作用域链中。

         当执行add函数时,JavaScript引擎需要解析函数里的num1和num2标识符,解析过程是检查作用域链中的每个对象,知道找到指定的标识符。查找从作用域链的第一个对象开始,这对象就是包含该函数局部变量的活动对象。如果在该对象中没有找到标识符,就会继续在作用域链中的下一个对象中查找标识符。一旦标识符被找到,查找就结束。本例中,因为num1和num2标识符存在于当前的活动对象中,所以不需要到全局对象中查找。

         理解JavaScript中如何管理作用域和作用域链很重要,因为在作用域链中要查找的对象个数直接影响标识符解析的性能。标识符在作用域链中的位置越深,查找和访问它所需要的事件就越长;如果作用域管理不当,就会给脚本的执行时间带来负面影响。

猜你喜欢

转载自blog.csdn.net/u014399368/article/details/81186522