最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

深入浅出JavaScript之闭包(Closure)的代码图文详细介绍

来源:懂视网 责编:小采 时间:2020-11-27 20:24:26
文档

深入浅出JavaScript之闭包(Closure)的代码图文详细介绍

深入浅出JavaScript之闭包(Closure)的代码图文详细介绍:闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。下面写下我的学习笔记~系列目录深入浅出JavaScript之闭包(Closure)深入浅出JavaScript之thi
推荐度:
导读深入浅出JavaScript之闭包(Closure)的代码图文详细介绍:闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。下面写下我的学习笔记~系列目录深入浅出JavaScript之闭包(Closure)深入浅出JavaScript之thi
闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。下面写下我的学习笔记~

系列目录

  • 深入浅出JavaScript之闭包(Closure)

  • 深入浅出JavaScript之this

  • 深入浅出JavaScript之原型链和继承

  • 闭包-无处不在

    在前端编程中,使用闭包是非常常见的,我们经常有意无意,直接或间接用到了闭包。闭包可以使传递数据更加灵活(比如处理一些点击事件)

    !function() { 
     var localData = "localData here"; 
     document.addEventListener('click', //处理点击事件时用到了外部局部变量,比如这里的localData 
     function(){ 
     console.log(localData); 
     }); 
    }();

    又比如下面这个例子:(是不是很亲切~~)

    !function() { 
     var localData = "localData here"; 
     var url = "http://www.baidu.com/"; 
     $.ajax({ 
     url : url, 
     success : function() { 
     // do sth... 
     console.log(localData); 
     } 
     }); 
    }();

    再来看一个例子~~这种情况就是我们通常所说的闭包

    function outer() { 
     var localVal = 30; 
     return function(){ 
     return localVal; 
     } 
    } 
    var func = outer(); 
    func(); // 30

    这个例子中调用outer()返回匿名函数function(),这个匿名函数中可以访问outer()的局部变量localVal,在outer()调用结束后,再次调用func()的时候,仍然能访问到outer()的局部变量localVal

    闭包的概念

    闭包,不同于一般的函数,它允许一个函数在立即词法作用域外调用时,仍可访问非本地变量。 –维基百科

    闭包就是能够读取其他函数内部变量的函数。 –阮一峰

    由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成”定义在一个函数内部的函数”。

    所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁

    闭包的用途

    这部分转自这篇博文

    闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    function f1(){
        var n=999;
        nAdd=function(){n+=1}
        function f2(){
          alert(n);
        }
        return f2;
      }
      var result=f1();
      result(); // 999
      nAdd();
      result(); // 1000

    在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

    为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

    这段代码中另一个值得注意的地方,就是”nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

    闭包-封装

    (function() { 
     var _userId = 23492; 
     var _typeId = 'item'; 
     var export = {}; 
    
     function converter(userId) { 
     return +userId; 
     } 
     export.getUserId = function() { 
     return converter(_userId); 
     } 
     export.getTypeId = function() { 
     return _typeId; 
     } 
     window.export = export; //通过此方式
    输出 }()); export.getUserId(); // 23492 export.getTypeId(); // item export._userId; // undefined export._typeId; // undefined export.converter; // undefined

    利用闭包的特性能让我们封装一些复杂的函数逻辑,在这个例子中调用export上的方法(getUserId,getTypeId)间接访问函数里私有变量,但是直接调用export._userId是没法拿到_userId的。这也是Node里面常用到特性吧~

    常见错误之循环闭包

    下面这个案例,我们添加3个p,值分别为aaa,bbb,ccc,我们想实现的是点击aaa输出1,点击bbb输出2,点击ccc输出3

    document.body.innerHTML = "<p id=p1>aaa</p>" + "<p id=p2>bbb</p><p id=p3>ccc</p>"; 
    for (var i = 1; i < 4; i++) { 
     document.getElementById('p' + i). 
     addEventListener('click', function() { 
     alert(i); // all are 4! 
     }); 
    }

    结果点击aaa,bbb还是ccc都是alert(4)~~

    产生这样的问题在于这个i的值在初始化完成的时候就已经是4了

    要达到我们想要的点击aaa输出1,点击bbb输出2,点击ccc输出3,要用到闭包的技巧,在每次循环的时候,用立即执行的匿名函数把它包装起来,这样子做的话,每次alert(i)的值就取自闭包环境中的i,这个i来自每次循环的赋值i就能输出1,2,3了

    document.body.innerHTML = "<p id=p1>aaa</p>" + "<p id=p2>bbb</p>" + "<p id=p3>ccc</p>"; 
    for (var i = 1; i < 4; i++) {
     !function(i){ //②再用这个参数i,到getElementById()中引用 
     document.getElementById('p' + i). 
     addEventListener('click', function() { 
     alert(i); // 1,2,3
     }); 
     }(i); //①把遍历的1,2,3的值传到匿名函数里面
    }

    思考题

    如果你能理解下面两段代码的运行结果,应该就算理解闭包的运行机制了。(来自阮老师)这题目总结得真秒~~

    代码片段一

    var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          return function(){
            return this.name;
          };
        }
      };
      alert(object.getNameFunc()());

    代码片段二

    var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          var that = this;
          return function(){
            return that.name;
          };
        }
      };
      alert(object.getNameFunc()());

    声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文档

    深入浅出JavaScript之闭包(Closure)的代码图文详细介绍

    深入浅出JavaScript之闭包(Closure)的代码图文详细介绍:闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。下面写下我的学习笔记~系列目录深入浅出JavaScript之闭包(Closure)深入浅出JavaScript之thi
    推荐度:
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top