作用域链是一个对象列表,上下文代码中出现的标识符将在这个列表中查找。
-
原理:
- 当代码在一个环境中执行时,会创建变量对象的一个作用域链。
- 作用域的前端始终是当前执行的代码所在环境的变量对象:
(1)如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(在全局环境中不存在)。
(2)作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境,一直到全局执行环境。
(3)全局执行环境的变量对象始终是作用域链中的最后一个对象。
-
查找规则:
- 如果一个变量在函数自身作用域(在函数自身的变量/活动对象)中没有找到,那么就会查找父级函数(外层函数)的变量对象,以次类推。
- 当解析(查找)一个标识符的时候,会从作用域链中的活动对象开始查找,然后(如果这个标识符在函数自身的活动对象中没有被查找到)向作用域链的上一层查找
-
作用:
保证对执行环境有权访问的所有变量和函数的有序访问。
-
注意:
内部环境通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中的任何变量和函数。
-
例子:
- 代码:
var a = 1;
function fn1() {
function fn2() {
console.log(a);
}
function fn3() {
var a = 4;
fn2();
}
var a = 2;
return fn3;
}
var fn = fn1();
console.log(fn);
fn();
分析:
- console.log(fn);执行打印--fn()函数的操作,调用函数fn1(),进入函数内部,返回一个函数fn3()。
- fn() -- 执行函数fn3(),在fn3()内部再调用了函数fn2(),进入fn2()的函数内部,console.log(a),构成了一条作用域链:
(1)首先在fn2()执行环境中寻找a变量,a不存在;
(2)然后顺着作用域链往上找,在fn1()函数的执行环境中寻找a变量,找到 var a = 2,然后直接打印 a = 2,不再往上去找a变量.
结果:
fn3() {
var a = 4;
fn2();
}
2
网友评论