作用域链
嵌套
作用域可以进行嵌套。词法与块级作用域可以相互包含:
function someFunc () {
function inner () {
}
}
inner函数 被嵌套在 someFunc函数所处的语法作用域中。
if (true) {
while (false) {
}
}
while 块级作用域被嵌套在if块级作用域中。
function someFunc () {
if (true) {
}
}
if创造的块级作用域被嵌套在 someFunc函数所创造的语法作用域中
作用域中变量的访问通道
所用可嵌套的作用域都遵循相同的规则:每个嵌套在内部的作用域都有一条访问外部作用域变量的通道,但反过来外部作用域无法访问内部作用域的变量。
举个栗子:
function someFunc () {
var outerVar = 1;
function inner () {
var innerVar = 2;
}
}
在inner函数内部可以访问 innerVal 与 outerVar 变量,但在someFunc函数中仅仅只能访问outerVar变量。
作用域多重嵌套
嵌套规则不限制只能嵌套一层,它允许进行多重作用域进行嵌套,并每层都遵循着允许访问上层作用域变量的规则。同时附加一条规则:相邻的作用域之间无法相互访问对方作用域中的变量。
举个栗子:
function someFunc () {
function inner () {
}
function inner2 () {
}
}
inner 和 inner2 函数 都被嵌套在 someFunc函数的作用域中。someFunc函数无法访问inner 和 inner2 函数中的变量。inner 函数无法访问 inner2函数中的变量,反之亦然。
作用域树
请看下面一个自上而下的作用域嵌套,一个条作用域树将被创建形成。
这是代码
function someFunc () {
function inner () {
}
function inner2 () {
function foo () {
}
}
}
生成的树形关系如下:
someFunc()
|
/ \
/ \
↓ ↓
inner() inner2()
↓
foo()
记住内部作用域可以访问外部作用域中的变量,但反之无效(如foo()函数可以访问inner2()函数中的变量,inner2()函数可以访问someFunc()函数中的变量)。话说回来,从下往上看更有树的感觉。当然,你也可以把它理解成一个链条。
作用域链
下面是一条从内部到外部形成的作用域链。
someFunc()
↑
inner2()
↑
foo()