0
点赞
收藏
分享

微信扫一扫

前端之JS闭包

单调先生 2022-04-21 阅读 58
前端

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();

闭包可以访问的作用域有三个:

  1. 闭包(也就是内部函数)作用域
  2. 外部函数的作用域
  3. 全局作用域
    所以上方代码是可以运行的。

词法作用域,也叫静态作用域,它的作用域是指在词法分析阶段就确定了,不会改变。

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
  1. 实用闭包
    闭包将函数与其所操作的某些数据(环境)关联起

可以修改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());
举报

相关推荐

0 条评论