闭包真的完全不能被gc吗?

72 阅读1分钟

chrome v8 gc机制

chrom v8的gc机制,核心理解就一句话——没有被使用的内容自动清理
这也是闭包利用的特点。

什么是闭包

闭包就是能够读取其他函数内部变量的函数。在有函数读取其他函数的内部变量时,本该在函数执行结束销毁的变量由于还在被使用就不会被销毁。

function createClosure() {
  let name = '';

  function changeName(_name) {
    name = _name;
    console.log(`the new name is ${name}`);
  }

  return changeName;
}

function useClosure() {
  // 这里存储了createClosure返回结果,产生了闭包。在useClosure方法运行周期内,createClosure的name不会被销毁。
  const useChangeName = createClosure();
  useChangeName('Jerry');
}

useClosure(); // the new name is Jerry
// useClosure执行完成后,内部变量都会被销毁,也包括useChangeName这个变量,
// 此时由于没有任何地方引用createClosure的返回值,createClosure中的name将被销毁。

为啥闭包会造成"内存泄露"?

原生js中,js文件最顶级直接使用var定义的变量,最终都会被挂载到window对象上。gc清理时看到该内容还有引用,就不会回收。

function createClosure() {
  let name = '';

  function changeName(_name) {
    name = _name;
    console.log(`the new name is ${name}`);
  }

  return changeName;
}

var useChangeName = createClosure();
useChangeName(); // the new name is Jerry
// 此时,useChangeName被挂载到了window上,虽然执行完了,但是window.useChangeName始终存在,
// 所以createClosure中的name不会被销毁。

// 若执行如下操作,createClosure中的name将被销毁。
delete window.useChangeName;