什么是作用域?
javascript没有块级作用域,只有函数作用域。
这是任何一本javascript基础书都会说到的一句话,可是什么是作用域呢,什么又是作用域链?先说几个概念
执行环境
代码在执行时所处的环境, 有全局环境和局部环境之分。全局环境即宿主对象,在web浏览器中,宿主对象就是window。局部环境就是javascript代码在执行函数时创建的执行环境。
变量对象
每个执行环境都有一个与之对应的变量对象,执行环境中所创建的变量都会添加到该对象的属性中,变量对象是我们访问不到的,window对象例外。这也是为什么在全局定义的变量我们可以使用window.name访问到。
而我们所说的访问一个作用域就是访问对应执行环境中的变量对象。简单点理解:
作用域就是对变量的一种管理约束
用鸡棚来举例,假如鸡是变量,鸡的活动就是代码执行,如果让鸡活得更好,你需要给它适应的环境(执行环境),同时你又担心它被别人吃了,或者你想吃的时候找不到它,就给它建了个鸡圈。但是你不可能天天看管着他,所以你雇佣一个人(变量对象)来帮忙打理鸡棚,而鸡的活动区域即鸡棚的范围就是作用域
这样你就可以思考一个问题,因为鸡在鸡棚里面,所以任何人在鸡棚外找不到鸡;等同于,变量在作用域内,任何人在作用域外都找不到该变量
什么是作用域链呢?
作用域链:
当使用一个变量时,首先查找当前变量对象上是否有该值,如果不存在该变量就像他的包含对象询问是否有该变量,如果依然不存在继续向包含对象的包含对象询问,直到找到全局对象,如果依然不存在就说明该变量不存在,如果中途在任何一个变量对象查找到该变量就返回该变量的值。包含对象:
外层执行环境的变量对象就是当前执行环境的包含对象,这里我们可以简单的理解为包含对象与当前的变量对象是从属关系。
上面了解了包含对象,我们继续以养鸡这个例子举例。首先你是你家的管理者,即你也可以认为是你家这个执行环境中的对象变量,而鸡棚的对象变量那个雇员和你是从属关系,那么也就可以认为你是鸡棚的包含对象。假如你养了一只猫,而这只猫的可以在你家的任何地方活动,即他的执行环境就是你家这个作用域。那这个鸡棚是属于你家的范围吗?当然属于!那么猫的活动范围就包含了鸡棚,所以猫是可以走到鸡棚里面去和鸡一起活动的。所以在鸡棚中我们是能看见猫的身影,即能找到猫这个变量。
那么也就可以理解其实当前执行环境中能访问到包含对象的变量,那么以此类推也能访问到包含对象的包含对象的变量,直到访问到宿主对象。也就是说,局部执行环境能访问包含他的所有执行环境的变量。而从当前环境通过层层包含对象一直到宿主对象形成的一条链就是作用域链。
举个栗子
博主已经没有例子可举了