作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。
全局和局部作用域下面用1张图来解释:
单纯的JavaScript作用域还是很好理解的。
全局履行环境是最外层的1个履行环境,在web阅读器中全局履行环境是window对象,因此所有全局变量和函数都是作为window对象的属性和放大创建的。每一个函数都有自己的履行环境,当履行流进入1个函数的时候,函数的环境会被推入1个函数栈中,而在函数履行终了后履行环境出栈并被烧毁,保存在其中的所有变量和函数定义随之烧毁,控制权返回到之前的履行环境中,全局的履行环境在利用程序退出(阅读器关闭)才会被烧毁。
当代码在1个环境中履行时,会创建变量对象的1个作用域链(scope chain)来保证对履行环境有权访问的变量和函数的有序访问。
用1张图来解释作用域链的运行:由里向外履行。
当1个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充,例如定义下面这样1个函数:
函数add的作用域将会在履行时候用到,例如履行以下代码:
这些值依照它们出现在函数中的顺序被复制到运行期上下文的作用域链中。它们共同组成了1个新的对象,叫“活动对象(activation object)”,该对象包括了函数的所有局部变量、命名参数、参数集合和this,然后此对象会被推入作用域链的前端,当运行期上下文被烧毁,活动对象也随之烧毁。新的作用域链以下图所示:
在函数履行进程中,没遇到1个变量,都会经历1次标识符解析进程以决定从哪里获得和存储数据。该进程从作用域链头部,也就是从活动对象开始搜索,查找同名的标识符,如果找到了就使用这个标识符对应的变量,如果没找到继续搜索作用域链中的下1个对象,如果搜索完所有对象都未找到,则认为该标识符未定义。
根据上述讲的作用域链的结构可以看出,定义的标识符的越深,那末读写的速度也就越慢,而全局变量总是处于作用域链的最末端,所以当变量解析的时候,查找全局变量是最慢的,所以在编写代码的时候要尽量少的使用全局变量,尽量使用局部变量。
上一篇 软考之进程,线程,管程比较