程序员人生 网站导航

理解javascript作用域和作用域链

栏目:互联网时间:2014-11-26 08:27:27

        作用域

   作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。

    全局和局部作用域下面用1张图来解释:

    

   单纯的JavaScript作用域还是很好理解的。

   


   作用域链

  全局履行环境是最外层的1个履行环境,在web阅读器中全局履行环境是window对象,因此所有全局变量和函数都是作为window对象的属性和放大创建的。每一个函数都有自己的履行环境,当履行流进入1个函数的时候,函数的环境会被推入1个函数栈中,而在函数履行终了后履行环境出栈并被烧毁,保存在其中的所有变量和函数定义随之烧毁,控制权返回到之前的履行环境中,全局的履行环境在利用程序退出(阅读器关闭)才会被烧毁。

  当代码在1个环境中履行时,会创建变量对象的1个作用域链(scope chain)来保证对履行环境有权访问的变量和函数的有序访问。

    用1张图来解释作用域链的运行:由里向外履行。

    

    当1个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充,例如定义下面这样1个函数:       

function add(num1,num2) { var sum = num1 + num2; return sum; }
在函数add创建时,它的作用域链中会填入1个全局对象,该对象包括了所有全局变量,以下图所示:



函数add的作用域将会在履行时候用到,例如履行以下代码:

function a(sum1,sum2){ var sum=num1+num2; return sum; } var tatal=a(5,10);
    履行此函数时会创建1个称为“运行期上下文(execution context)”的内部对象,运行期上下文定义了函数履行时的环境。每一个运行期上下文都有自己的作用域链,用于标识符解析,当运行期上下文被创建时,而它的作用域链初始化为当前运行函数的[[Scope]]所包括的对象。    

    这些值依照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了1个新的对象,叫“活动对象(activation object)”,该对象包括了函数的所有局部变量、命名参数、参数集合和this,然后此对象会被推入作用域链的前端,当运行期上下文被烧毁,活动对象也随之烧毁。新的作用域链以下图所示:

    

    在函数履行进程中,没遇到1个变量,都会经历1次标识符解析进程以决定从哪里获得和存储数据。该进程从作用域链头部,也就是从活动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没找到继续搜索作用域链中的下1个对象,如果搜索完所有对象都未找到,则认为该标识符未定义。

   


    总结

  根据上述讲的作用域链的结构可以看出,定义的标识符的越深,那末读写的速度也就越慢,而全局变量总是处于作用域链的最末端,所以当变量解析的时候,查找全局变量是最慢的,所以在编写代码的时候要尽量少的使用全局变量,尽量使用局部变量。

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐