重学js-作用域及作用域链

说到作用域,就要提一句他的两个兄弟:

引擎:负责整个javascript程序的编译及执行过程

编译器:js虽说是动态、解释执行的语言,但也是有编译这一过程,要不然如何执行呢,只是这一编译过程不需要提前编译。编译器主要是负责词法编译和代码生成

作用域:负责收集维护所有的声明的标识符组成的一系列的查询,并实施一套严格的规则,保证当前执行代码对这些标识符的访问权限。

先说一下执行环境,也就是作用域

执行环境内部定义了变量或函数有权访问的其他数据,决定他们各自的行为;每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。解析器在处理数据时会使用它,我们无法访问。每个函数都有一个自己的执行环境。

作用域链(scope chain

长得有点像数组的这么一个东西,存放作用域的变量对象,这里保存的变量对象也只是变量对象的指针,保证能够有序的 访问作用域 有权访问的所有变量和函数。作用域链的前端,始终都是当前执行的代码所在作用域的变量对象,作用域链的末端,始终都是全局作用域的变量对象。

当前作用域如果对上一层执行环境定义的变量或函数有引用时,那么作用域链就会添加相应的作用域变量对象,如果没有引用时那么是不会添加进去的,比如:

主要看test6这个函数,对test4作用域中定义的变量有引用,因此作用域链能看到test4;对test3中定义的变量和函数没有引用,因此作用域链不会添加,然后调用一下test5看看:

能看到作用域链增加了test3;

标识符解析是沿着作用域链一级一级地搜索,从最前端开始,往后回溯,找到最末端如果还没有找到,则会提示错误,如果中途找到就会停止搜索,返回结果,不在进入另一个变量对象;

LHS查询和RHS查询

js引擎在作用域中查找变量的方式,RHS查询是查找某个变量的值(取到变量的源值),可以看做赋值操作右侧的查询;LHS查询是试图找到变量的容器本身,从而可以对其进行赋值,可以看做赋值操作左侧的查询;这里的赋值操作的左右侧不等于‘=赋值操作的左右侧’;比如:

var a = 1;

先是声明一个变量,变量存在在作用域中,然后变量a进行LHS查询,取得变量a的储存容器,然后给它赋值1;

console.log(a);

执行以上操作,这里是进行一次RHS查询操作,然后将得到的值传递给console.log;console本身也会进行一次RHS查询,查找console对象有没有log的方法

function foo(a){

     console.log(a);

}

foo(2);

在foo函数调用中,既有LHS查询,又有RHS查询;因为在函数传参中会有一个 a = 2;的隐式赋值操作;

如果查找的目的是对 变量进行赋值,那么就会使用 LHS 查询;如果目的是获取变量的值,就会使用 RHS 查询。赋值操作符会导致 LHS 查询。=操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。

 

延长作用域链

with语句

会向作用域链的最前端添加一个变量对象,变量对象会包含with语句接收对象的所有属性和方法,因此在语句内部,既然作用域链最顶端的变量对象包含了传递给with语句对象的所有属性和方法,那么语句内部就可以直接使用属性名,比如:平时访问对象是这样obj.attr,那么在这里就可以直接attr获取属性值,例子就不写了,with语句有写。

 

块级作用域

es6之后,有了块级作用域,但需要通过const let 声明,块级作用域以外是不能访问作用域内的变量。

for循环,常见例子:

第一个表现是形成块级作用域,这个作用域其实由两部分构成,一部分外层作用域,一部分是for循环后紧跟的{}作用域,外层作用域会记录i每一次表达式执行后的值,紧跟的作用域则是单独每一次i的值,相当于每次都有一个let i的操作;

第二个则是var 定义作用域内的变量,每一轮循环则是修改这个变量的值

 

垃圾收集

js有自动垃圾收集机制,怎么收集呢?就是有一个垃圾收集器,然后按照固定的时间间隔(或代码执行中预定的收集时间), 周期性地执行找出那些不再继续使用的变量,然后释放其占用的内存这么一个操作;

局部变量的正常生命周期只在函数执行的过程中存在,当函数执行完毕后,响应的内存就会被释放掉

js有自动垃圾回收,我们是不是就可以不关心内存管理了呢?

内存的生命周期都是:分配内存,内存读写,不需要时归还内存;

先js引擎大多使用标记清除法,来判断哪些内存应该被释放掉;

实现垃圾收集常用的就是引用计数,标记清除,节点复制三种方法,

了解更多垃圾回收上的东西,可以读一读Richard Jones和Rafael Lins写的《Garbage Collection》一书:

链接: https://pan.baidu.com/s/17Ebkz4S4GYYEfuNZUW_pAg 提取码: 8xd7

 

这里就先放一放,先知其然,再知其所以然

 

 

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值