zoukankan      html  css  js  c++  java
  • javascript的闭包

    闭包

    为什么需要闭包

    闭包是一个比较容易搞混的地方,不知道闭包是干嘛的就强行学习,结果只能学个不明不白。在了解为什么需要闭包之前,需要先看看javascript特殊的变量作用域。

    javascript可以在函数内部读取全局变量!

    var a = 1;
    function test()
    {
        a = 3;
        alert(a);
    }
    
    test(); 
    

    输出结果是3,这在c++里是完全不能理解的,全局变量你函数怎么访问到的?

    回味一下c++的处理方式,局部变量,参数变量存放在栈中,当离开作用范围后,分配的内存在作用范围外会被系统自动回收。new出来的内存空间存放在堆中,不受作用域管理,不会被系统自动回收,只有在使用delete删除或者整个程序结束后才会释放内存。

    记住这个后,为什么需要闭包就呼之欲出了,如果我们需要只在函数内部访问的变量,那就再嵌套一层呗,把当前函数当作全局,那往下的一层函数不久可以访问当前函数的变量了吗?(套娃?)

    function test()
    {
        var a = 3;
        function taowan()
        {
            alert(a);
        }
        return taowan;//返回套娃
    }
    
    var t = test(); //接收套娃
    t(); //输出3
    

    这个套娃把上一层套娃的记忆(变量a)带出来了,也就是说,虽然外面的壳没了,但是变量a却永远存在了它的心中。

    闭包的作用

    闭包的定义是:在函数中使用未在函数中定义但在函数所处上下文有效的变量(标识符)与函数本体的集合。闭包允许函数附带变量,形成自己的一片天地,有点像面向对象中对象的一个属性附带的方法。下面举几个例子说明闭包的强大作用。此例来自火狐开发者网站https://developer.mozilla.org

    var makeCounter = function() {
      var privateCounter = 0; //私有
      function changeBy(val) {
        privateCounter += val;
      }
      return {
        increment: function() {
          changeBy(1);
        },
        decrement: function() {
          changeBy(-1);
        },
        value: function() {
          return privateCounter;
        }
      }  
    };
    
    var Counter1 = makeCounter();
    var Counter2 = makeCounter();
    console.log(Counter1.value()); /* logs 0 */
    Counter1.increment();
    Counter1.increment();
    console.log(Counter1.value()); /* logs 2 */
    Counter1.decrement();
    console.log(Counter1.value()); /* logs 1 */
    console.log(Counter2.value()); /* logs 0 */
    

    该共享环境创建于一个立即执行的匿名函数体内。这个环境中包含两个私有项:名为 privateCounter 的变量和名为 changeBy 的函数。这两项都无法在这个匿名函数外部直接访问。必须通过匿名函数返回的三个公共函数访问。什么意思呢?就是闭包可以模拟私有方法,把函数做成接口,只有此对象才可以访问。

    而且因为闭包可以储存变量,所以我们可以把两个变量的函数封装成只需要一个变量:

    function make_pow(n) {
        return function (x) {
            return Math.pow(x, n);
        }
    }
    
    // 创建两个新函数:
    var pow2 = make_pow(2);
    var pow3 = make_pow(3);
    
    console.log(pow2(5)); // 25
    console.log(pow3(7)); // 343
    

    希望这篇文章能让你理解闭包,如果我对闭包有新的认识,还会加入进去的!

  • 相关阅读:
    react-router JS 控制路由跳转(转载)
    vue 将值存储到vuex 报错问题
    封装GetQueryString()方法来获取URL的value值(转载)
    vue 里面的watch 选项详解
    谷歌地图api 开发 (转载)
    es6 ...展开运算符
    关于localStorage 应用总结
    js 刷新当前页面会弹出提示框怎样将这个提示框去掉
    深入浅析JavaScript的API设计原则(转载)
    jQuery mouseover与mouseenter,mouseout与mouseleave的区别
  • 原文地址:https://www.cnblogs.com/lyc1226/p/12109905.html
Copyright © 2011-2022 走看看