js 闭包 函数执行完后会干什么

2020-07-07  本文已影响0人  IamaStupid

先看一段代码:

<script type="text/javascript">
...
function outer () {
  let a = 123;
  function inner () {
    console.log(a);
  }
  inner();
}
outer();
let bb = 1;
...
</script>

这段代码执行完outer(),理论上outer函数作用域下的内存就销毁了,再也不存在了,所以outer函数作用域内的变量再也访问不了。
(严格来说,当函数运行到这段代码块结尾后,对应的执行上下文被弹出 stack 执行栈,等待引擎回收器回收分配出去的内存)
但outer函数并不会被销毁(因为这段代码中outer函数属于全局上下文,只要全局上下文没销毁,全局上下文里面的变量是不会被销毁的),所以还是可以再次执行outer函数的,再次调用的时候,outer函数所有变量回到初始状态(代码重新跑一遍)
如果修改一下代码:

function outer () {
  let a = 123;
  let b = {a: a}
  function inner () {
    console.log(a);
  }
  return inner;
}
var ob = outer();
let bb = 1;
...

执行完outer函数后,给全局作用域下的ob赋值inner函数,由于script下的代码属于全局作用域,在页面销毁之前,全局作用域下的变量是不会销毁的,所以即便所有代码执行完毕,ob也不会被销毁,从而被引用inner函数也不会被销毁,所以outer函数作用域也不能销毁,这样,回收机制就无法回收outer函数作用域分配出去的内存,导致内存泄漏。

上面的那种情况ob就是闭包,但如果outer函数return b 对象,你就不能说对象b形成了一个闭包。

JavaScript中的函数才会形成闭包。 闭包是由函数以及声明该函数的词法环境组合而成的。该环境包含了这个闭包创建时作用域内的任何局部变量。

那闭包内存溢出的问题怎么可以解决? 用完ob之后,设置ob = null 这样就可以了。

复杂的版本:
https://www.jianshu.com/p/0aed3c135a1c
https://www.jianshu.com/p/f58c030182b4

上一篇 下一篇

猜你喜欢

热点阅读