JS闭包
闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
简言之,闭包就是函数内部的函数(而且这个内部函数可以访问外部函数内的作用域)。
function outside() {
  var name = 'closure'; //外部变量
  function inside() {//闭包,一个内部函数
    alert(name);
  }
  inside();//使用内部函数
}
outside();
用法
使用var声明变量,在方法内部是局部变量,在方法外部是全局变量
function outside() {
  var name = 'closure';
  function inside() {
    alert(name);
  }
  return inside;
}
var myFunc = outside();
myFunc();
闭包可以访问的作用域有三个:
- 闭包(也就是内部函数)作用域
- 外部函数的作用域
- 全局作用域
 所以上方代码是可以运行的。
词法作用域,也叫静态作用域,它的作用域是指在词法分析阶段就确定了,不会改变。
2.函数工厂
 返回一个函数。
 静态作用域内容不同
    function outside(x) {
      return function inside(y) {
        return x + y;
      }
    }
    var myFunc = outside(2); //x
    const z = myFunc(3); //y
    console.log(z); //x+7
- 实用闭包
 闭包将函数与其所操作的某些数据(环境)关联起
可以修改body字体大小的按钮
<body>
  <p>字体大小</p>
  <button>size-12</button>
  <button>size-14</button>
  <button>size-16</button>
  <script>
    function makeSizer(size) {
      return function inside(y) {
        document.body.style.fontSize = size + 'px';
      }
    }
    const btn = document.querySelectorAll('button');
    var size = [];
    size[0] = makeSizer(12);
    size[1] = makeSizer(14);
    size[2] = makeSizer(16);
    for (let i = 0; i < btn.length; i++) {
      btn[i].onclick = size[i];
    }
  </script>
</body>
用闭包模拟私有方法 – 模块模式=自调用函数+闭包
模块模式是 js 设计模式的一种。
 Java支持将方法声明为私有的,它们只能被同一个类中的其它方法所调用。
 js中我们可以使用闭包来模拟私有方法。
    var Counter = (function () {
      // 私有变量和方法
      var privateCounter = 0;
      function changeBy(val) {
        privateCounter += val;
      }
      return { // 闭包--------------------------------------------------
        // 公有变量和方法
        increment: function () {//自加
          changeBy(1);
        },
        decrement: function () {//自减
          changeBy(-1);
        },
        value: function () {//值
          return privateCounter;
        }
      }
    })();
    console.log(Counter.value()); /* logs 0 */
    Counter.increment();
    Counter.increment();
    console.log(Counter.value()); /* logs 2 */
    Counter.decrement();
    console.log(Counter.value()); /* logs 1 */
自调用函数,函数定义完之后会立即运行的函数。
 语法:
(function () {
	func body...	
})();
复用:
 makeCounter 是函数的引用,
 makeCounter() 调用函数,返回一个对象,以此达到函数的复用。
    var makeCounter = function () {
      // 私有变量和方法
      var privateCounter = 0;
      function changeBy(val) {
        privateCounter += val;
      }
      return {
        // 暴露出的共有变量和方法
        increment: function () { //自加
          changeBy(1);
        },
        decrement: function () { //自减
          console.log(this)
          changeBy(-1);
        },
        value: function () { //值
          return privateCounter;
        }
      }
    };
    var counter1 = makeCounter();
    var counter2 = makeCounter();
    console.log('counter1:', counter1.value());
    console.log('counter2:', counter2.value());
    counter1.increment();
    counter1.increment();
    console.log('counter1:', counter1.value());
    counter2.decrement();
    console.log('counter2:', counter2.value());
    console.log(counter1.value(), counter2.value());










