14

闭包

图片描述

一、认识闭包

闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境(包含自由变量)。环境由闭包创建时在作用域中的任何局部变量组成。

二、闭包的产生

function f() {
  var a = 2;
  var b = 3;
  function g(){
    console.log(a);
  }  
  g();
}
f();

这就形成了一个闭包,函数g以及其所在的环境以及其中的自由变量就组成了一个闭包。

创建闭包最常见方式,就是在一个函数内部创建另一个函数。下面例子中的 closure 也是一个闭包:

function func(){
  var a = 1,b = 2;
  
  function closure(){
    return a+b;
  }
  return closure;
}

下面也是一个闭包

function f1() {
  var a = 10;
  var b = 20;
  return function g() {
    console.log(a);
  }
}

var result = f1;
result()(); // 10

三、闭包的好处

实例 1 累加 【减少全局变量个数】

function add () {
  var a  = 0;
  return function () {
    a++;
    alert(a);
  }
}

var result = add();
result(); // 1
result(); // 2

实例 2 【减少传递参数的个数】

function callFac(base) {
  return function (max) {
    var total = 0;
    for(var i = 1; i <= max; i++) {
      total+=i;
    }
    return total + base;
  }
}

var result = callFac(2);
result(3); // 8

实例 2 【封装】

(function () {
  var a = 0;
  function getM() {
    rerurn a;
  }
  function setM(val) {
    a = val;
  }
  window.g = getM;
  window.s = setM;
})();

s(3);

三、闭包的注意点

1、 对捕获的变量只是个引用,不是复制

function f() {
  var num = 0;
  function g () {
    alert(num); // 这里使用的是引用
  }
  num ++;
  g(); // 在调用执行之前就已经加 1了
} 
f();

2、每调用一次父函数,就会产生一个新的闭包

function f() {
  var num = 1;
  return function () {
    num++;
    alert(num);
  }
}

var result1 = f();
result1(); // 2
result1(); // 3

var result2 = f();
result2(); // 2
result2(); // 3

3. 循环

<ul>
    <li id="1">1</li>
    <li id="2">2</li>
    <li id="3">3</li>
  </ul>
  <script>
    for(var i = 1 ; i <= 3; i++) {
      var el = document.getElementById(i);
      el.onclick = function() {
        alert(i);
      }
    }
  </script>

  // 结果是无论点击那个,都是弹出4
// 解决办法
<ul>
    <li id="1">1</li>
    <li id="2">2</li>
    <li id="3">3</li>
  </ul>
  <script>
    for(var i = 1 ; i <= 3; i++) {
      var el = document.getElementById(i);
      el.onclick = (function(id) {
        return function () {
          alert(id);
        }
      })(i);;
    }
  </script>

Meils
1.6k 声望157 粉丝

前端开发实践者