JavaScript 里一切都是对象, 包括函数. 函数对象和其它对象一样, 拥有可以通过代码访问的属性和一系列仅供 JavaScript 引擎访问的内部属性. 其中一个内部属性是作用域, 包含了函数被创建的作用域中对象的集合, 称为函数的作用域链.
作用域:
作用域就是变量与函数的可访问范围, 即作用域控制着变量与函数的可见性和生命周期. 可以说, 变量和函数在什么时候可以用, 什么时候被摧毁, 这都与作用域有关.
JavaScript 中, 变量的作用域有全局作用域和局部作用域两种.
1. 全局作用域(Global Scope)
在代码中任何地方都能访问到的对象拥有全局作用域, 一般来说以下几种情形拥有全局作用域:
(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域
(2)所有末定义直接赋值的变量自动声明为拥有全局作用域
(3)所有 Windows 对象的属性拥有全局作用域
一般情况下, Windows 对象的内置属性都拥有全局作用域, 例如 Windows.name,Windows.location,Windows.top 等等.
2. 局部作用域(Local Scope)
和全局作用域相反, 局部作用域一般只在固定的代码片段内可访问到, 最常见的例如函数内部, 所有在一些地方也会看到有人把这种作用域称为函数作用域.
当 JS 解析器执行时, 首先就会在执行环境里构建一个全局对象, 我们定义的全局属性就是做为该对象的属性读取, 在顶层代码中我们使用 this 关键字和 Windows 对象都可以访问到它.
而函数体中的局部变量只在函数执行时生成的调用对象中存在, 函数执行完毕时局部变量即刻销毁. 因此在程序设计中我们需要考虑如何合理声明变量, 这样既减小了不必要的内存开销, 同时能很大程度地避免变量重复定义而覆盖先前定义的变量所造成的 Debug 麻烦.
作用域链:
当代码在一个环境中执行时, 会创建变量对象的一个作用域链 (scope chain, 不简称 sc) 来保证对执行环境有权访问的变量和函数的有序访问. 作用域第一个对象始终是当前执行代码所在环境的变量对象(VO)
- function a(x,y){
- var b=x+y;
- return b;
- }
在函数 a 创建的时候它的作用域链填入全局对象, 全局对象中有所有全局变量
如果执行环境是函数, 那么将其活动对象 (activation object, AO) 作为作用域链第一个对象, 第二个对象是包含环境, 下一个是包含环境的包含环境
- function a(x,y){
- var b=x+y;
- return b;
- }
- var tatal=a(5,10);
这时候 var total=a(5,10); 语句的作用域链如下
在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程, 从第一个对象开始, 逐级向后回溯, 直到找到同名标识符为止, 找到后不再继续遍历, 找不到就报错.
来源: http://www.css88.com/qa/javascript/11369.html