JavaScript闭包(Closure)

303 阅读2分钟

一:变量的作用域

学习闭包之前,必须理解JavaScript的变量作用域。

变量的作用域无非就是两种:全局变量局部变量

  • 函数内部可以直接读取全局变量
const a = 'xss';

function f1() {
    console.log(a);
}

f1();  // xss
  • 函数外部自然无法读取函数内部的局部变量
function f1() {
    var a = 'xss';
}

console.log(a); // undefined

二:如何从外部读取到局部变量?

  • 在函数的内部,再定义一个函数
function f1() {
  const a = 'xss';
  
  function f2() {
    const b = 'disable';
    console.log(a); // xss
  }
  console.log(b); // b is not defined
  f2();
}

f1();
// xss
// b is not defined

上述代码中,函数f2被包括在f1的内部,所以f1内部所有的局部变量,对f2都是可见的。但是反过来是不行的,f2的局部变量对f1是不可见的.

f2可以读取到f1中的局部变量,当把f2作为返回值时,我们就可以在f1外部读取f1的内部变量了。

function f1() {

  var n = 'xss';

  function f2() {
    console.log(n); // xss
  }

  return f2;

}

const res = f1(); // f2

res(); // xss

三:闭包的概念:

上述代码中,f2函数就是闭包,闭包能够读取其他函数内部变量的函数

由于在JavaScript语言中,只有函数内部的自函数才能读取局部变量,因此可以把闭包简单理解成‘定义在一个函数内部的函数’。

所以,本质上,闭包就是将函数内部与函数外部连接起来的一座桥梁。

四:使用闭包的注意事项

  • 由于闭包会使得函数中的变量都存在与内存中,内存消耗很大,所以请勿滥用闭包,否则会造成网页性能问题,在IE中可能导致内存泄漏。

解决方法: 退出函数前,将不使用的局部变量全部删除

  • 闭包会在父函数外部改变父函数内部的值。

原文:阮一峰的网络日志-学习JavaScript闭包(Closure)