JS作用域链

定义

当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境(执行上下文)有权访问的所有变量和函数的有序访问。

它有两个对象

  1. 变量对象(VO):变量对象即包含变量的对象,变量对象我们无法访问,除此之外和普通对象没什么区别。变量对象存储了在上下文中定义的变量和函数声明
  2. 活动对象(AO):是在进入函数执行环境时刻被创建的,它通过函数的 arguments 属性初始化。

变量对象和活动对象的关系

未进入执行阶段之前,变量对象(VO)中的属性都不能访问,只是声明但是进入执行阶段之后,变量对象(VO)转变为了活动对象(AO),里面的属性都能被访问了,然后开始进行执行阶段的操作。它们其实都是同一个对象,只是处于执行环境的不同生命周期。AO 实际上是包含了 VO 的。因为除了 VO 之外,AO 还包含函数的 parameters,以及 arguments 这个特殊对象。也就是说 AO 的确是在进入到执行阶段的时候被激活,但是激活的除了 VO 之外,还包括函数执行时传入的参数
和 arguments 这个特殊对象。

  1. 查看当前作用域,如果当前作用域声明了这个变量,可以直接访问
  2. 查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明,有就返回变量,没有继续下一步
  3. 再查找上级函数的上级函数,直到全局作用域为止,有则返回,无则继续
  4. 如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)

那么让我们来看看几个例子

  • 例子一
function fun(num){
    var age = 20;
    num();
}
fun(function(){
    console.log(age);//报错
    //1.在当前作用域没有查找到age
    //2.查找上一级作用域:全局作用域
    //为何是全局作用域?因为看上一级作用域,不是看函数在哪调用,而是看函数在哪编写的。
    //这种特别的作用域,叫做“词法作用域”
})

现在我们来分析下作用域链如何查找变量的:

  1. console.log(age)的时候,在当前作用域并没有查询到age变量。所以查找上一级作用域。
  2. 上级作用域是谁?这里需要引出一个概念,查找函数上级作用域,不是看函数在哪调用,而是看函数在哪编写。所以这样来看,上级作用域就是全局作用域。
  3. 在全局作用域中并没有声明age变量,所以console.log(age);就会报错。
  • 例子二
		var b = 100;
		function fn(){
			var a = 100
			function fun1(){
				console.log(c);//undefined
				a += 10;
				var c = 10;
				function fun2(){

				}
				fun2();
			}
			console.log(a);//100
			fun1();
			console.log(a);//110
			console.log(b);//100

		}
		fn();
	作用域链:有多级作用域连续引用新城的链式结构,管控一切变量的使用顺序  
				先在自己的AO中找,就延作用域链向父级作用域中去找
		GO{
			a : undefined,
			fn : function ...
		}
		fnAO{
			b : 10,
			fun1: function...,

		}
		fun1AO{
			c : 20;
		}

当前作用域查到了变量,则不会再继续寻找,直接返回该变量的值,这里打印的时候变量声明但是未赋值,所以c输出undefined。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值