js执行上下文及从这个角度理解闭包

是什么

js引擎在执行代码前会做些准备工作:就是创建对应的执行上下文,它可以理解为代码块执行时的环境,这个环境中包含了代码块要用的变量、函数、this等。
js引擎会以栈的方式来处理这些环境:
进栈相当于进入代码执行的环境,出栈相当于离开这个环境。
这个栈被称为函数调用栈。

分类

执行上下文可分为三类:

  1. 全局上下文,代码一开始运行时必定会首先进入该环境
  2. 函数上下文,当函数被调用时,会创建该函数的执行上下文
  3. eval上下文,查阅很多都说不用管,不会用到,那就不管啦
组成及创建

由三部分组成:

  1. 变量对象,用于保存这个环境中的变量和函数声明
    变量对象可以看JS变量对象详细解释
  2. 作用域链,是一个单向链表,表里面有未被销毁的变量对象
  3. this指针
执行过程

这里举例子更直观些:

function a() {
	console.log('a')
    function b() {
    	console.log('b')
    }
    b() 
}
a()

最开始一定是创建全局上下文,并为它分配地址,然后进入函数调用栈
执行a(),创建a的全局上下文,并为它分配地址,上下文进入函数调用栈,
执行a时遇到b(),创建b的全局上下文,并为它分配地址,进入函数调用栈
b函数执行完,出栈,b的上下文没有被引用,被垃圾回收,然后继续执行a函数
a函数执行完,出栈,a的上下文没有被引用,被垃圾回收
当页面关闭时,全局上下文才出栈,失去引用,被垃圾回收

由此我们可以发现:
栈底永远是全局上下文,栈顶就是当前执行上下文。
要注意的是,每次函数被调用,就会为其创建新的执行上下文,即使是同一个函数。

基于此,我们来解释下闭包,先拿个例子

function a(){
    var x =1
    return function(){	//函数可以访问外部x
        x++
        console.log(x)
	}
}
var add = a()
var add2 = a()
add()
add()
add2()
add2()

输出为:2,3,2,3

先是全局上下文入栈,然后a函数的执行上下文入栈,执行到return,出栈,这时我们把返回值保存了下来,变量add为a函数返回的匿名函数在内存中的地址引用,这就说明函数a的执行上下文中的东西仍然有被用到,所以并没有被垃圾回收,还保存在内存中,所以就还可以访问到其中变量。
因为函数每次调用都回创建新的执行上下文,所以add和add2可访问的x所在的上下文处在内存不同地址,所以不是同一个x。
用到闭包的地方很多,明天再写一篇总结归纳下吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值