JavaScript 闭包

62 阅读2分钟

闭包

闭包(closure)让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。闭包的作用:通过一系方法,将函数内部的变量 (局部变量)转化为全局变量。 我的理解是,闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。 所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

变量作用域

要理解闭包,首先必须理解Javascript特殊的变量作用域。变量的作用域无非就是两种:全局变量局部变量

1、函数内部可以直接读取全局变量
var n=999;
function f1(){
    alert(n);
}
f1(); // 999

2、函数外部自然无法读取函数内的局部变量
function f1(){
    var n=999;
}
alert(n); // error

3、需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量
function f1(){
    n=999;
}
f1();
alert(n); // 999

使用例子

function init() {
  var name = "Mozilla"; // name 是一个被 init 创建的局部变量
  function displayName() { // displayName() 是内部函数,一个闭包
      alert(name); // 使用了父函数中声明的变量
  }
  displayName();
}
init();

function makeFunc() {
    var name = "Mozilla";
    function displayName() {
        alert(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12

注意事项

1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除 2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。