手记

JavaScript 运行堆栈与闭包

2022-05-12 11:21:371773浏览

北瑶

1实战 · 1手记

运行堆栈

前提-高阶函数

在 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人推荐
随时随地看视频
慕课网APP