为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript 运行堆栈与闭包

运行堆栈

前提-高阶函数

在 JS 中,函数做为 第一等公民,与变量具有同等地位,函数不仅是一个可执行的代码段,还可以作为变量进行传递;因此,函数所存储的代码段,就可以在任意地方调用,但是 JS 中的函数永远在声明的地方执行 (词法作用域)

作为实参传入时,会形成一个 回调函数

作为参数返回时,会形成一个 闭包

堆栈执行-关键名词解释

JS 代码的运行,是需要先向内存申请存储空间,然后存入内存后运行的。JS 申请的这部分内存,我们可以叫做 执行环境栈(也被称为: ESC )

在执行环境栈中,会先创建全局代码执行所需要的空间,这个空间叫做 全局执行上下文 (也被称为 ECG ),全局作用域中的声明和变量,会被存入全局变量对象中,也就是在全局执行上文中的一个空间,也被叫做 VOG

在执行环境栈中,还会给不同的代码段 (函数、模块),申请一个当前代码运行所需要的空间,这个空间叫做 当前执行上下文

而我们所使用内置对象 ( JSON、setTimeout……),会被存放在 全局对象 ( 也叫 GO ) 中。

简单模型的执行堆栈

var i = 100
var g = i 
g = 101 
console.log(i)

编译阶段
简单模型的执行堆栈

执行阶段
图片描述

对象模型的执行堆栈

var i = {x:66}
var g = i
g.y = 77
console.log(i.y)

编译阶段

图片描述
执行阶段

图片描述

图片描述

函数模型的执行堆栈

编译阶段

图片描述

执行阶段-001
图片描述
执行阶段-002

图片描述

闭包

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

闭包解析

图片描述

闭包执行

图片描述

1:闭包可以保存数据,也就是说如果我们想延长某些数据的生命,那么就可以放在闭包里。所以如果我们使用闭包保存大量的数据,必然对空间是一种消耗

2:闭包里的数据什么时候被回收呢?(没人用人的时候 GC(清洁工))

3:GC有它自己的工作周期 (GC就员V8当中的一个模块)

4:GC并没有那么的智能,我们为了提高回收的效率在代码可以将一世后续无须再使用的数据置为 null

var lg = 1
function fun() {
  var lg = 2
  return function (a) {
    console.log(a + lg++);
  }
}
var f = fun()
f(3)
f(4)
f=null

5:回收不是一个变量名,名字是在栈区里的,回收的是这个名字所指向空间

闭包的练习题

let m = 5
function foo(m) {
  return function (n) {
    console.log(n + (++m))
  }
}

let fn = foo(8)
fn(10)
foo(11)(13)
fn(20)
console.log(m)

// =================

let m = 10,
  n = 10
function foo(m) {
  foo = function (n) {
    console.log(m + n++)
  }
  console.log(m++)
}

foo(5)
foo(7)

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消