本文内容: 1、什么是作用域?执行环境、变量对象; 2、什么是作用域链? 3、扩展:延长作用域链的两条语句with与catch
作用域链是javascript中常见的一个概念,想要理解作用域链,首先要理解好下面的两个概念:执行环境(常说的作用域)和变量对象。
作用域 == 执行环境
首先在其他语言中所说的作用域,在javascript中也叫执行环境,通常把作用域叫作执行环境,在javascript高级程序设计这本书中也是称为“执行环境”。 那么到底什么是执行环境呢?
执行环境
执行环境是javascript中的一个重要概念,它定义了变量或者函数有权访问的数据。执行环境有两种类型:全局执行环境和局部执行环境,其中局部执行环境就是指函数。(也可以说javascript作用域有两种,全局作用域和局部作用域) 全局执行环境是最外围的一个执行环境,如在Web浏览器中,全局执行环境就是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。 另外还有一个与之相关的重要概念,就是变量对象。
变量对象
每一个执行环境(每一个作用域)都有一个与之关联的变量对象,环境定义的所有变量和函数都保存在这个对象中(我们是无法访问到这个对象的,它的作用是解析器处理数据时会在后台使用它)。
作用域链
作用域链,顾名思义是一条链式结构,而这条链的每一个节点应该是作用域。又因为作用域即执行环境,上面说到每个执行环境都有一个与之关联的变量对象,因此可以说作用域链是这样的一条链:
var a = 1
function fn1 () {
var b = 2
fn2()
console.log(a,b) // 1,2 此时只能访问a,b, 访问c会报错
function fn2() {
var c = 3
console.log(a,b,c) // 1, 2, 3,这里a,b,c全部能够访问
}
}
fn1()
console.log(a) // 1 此时只能访问a, 访问b,c会报错
上面的代码涉及了三个执行环境:全局环境、fn1()的局部环境和fn2()的局部环境。在全局执行环境中只有一个变量a和函数fn1(),在函数fn1()的局部环境中有一个变量b和函数fn2(),但是在此执行环境中除了b和fn2还可以访问变量a,因为全局环境是它的父执行环境。在fn2()的局部环境中,有一个变量c,除了变量c,这个执行环境中还可以访问全局环境中的变量a和它的直接父执行环境fn1()中的变量b。下面的图可以形象的展示这个作用域链。
扩展
有两个语句,可以使作用域链的前端增加一个变量对象: catch和with;