zoukankan      html  css  js  c++  java
  • 自己对闭包的理解(保证能看懂)

    看了很多的关于闭包的文章,你不是还是一头雾水,还是不理解闭包的意义。

    最近我看了一篇文章,关于闭包的讲解,可以说是讲得非常通俗易懂,于是记录下来,以便加深理解。

    1、概念

    闭包函数:声明在一个函数中的函数,叫做闭包函数。

    闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。

    2、特点

      让外部访问函数内部变量成为可能;

      局部变量会常驻在内存中;

      可以避免使用全局变量,防止全局变量污染;

      会造成内存泄漏(有一块内存空间被长期占用,而不被释放)

    3、闭包的创建:­­­

    闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。闭包会发生内存泄漏,每次外部函数执行的时 候,外部函数的引用地址不同,都会重新创建一个新的地址。但凡是当前活动对象中有被内部子集引用的数据,那么这个时候,这个数据不删除,保留一根指针给内部活动对象。

    闭包内存泄漏为: key = value,key 被删除了 value 常驻内存中; 局部变量闭包升级版(中间引用的变量) => 自由变量;

    看到这里你是不是已经懵了,不知道在讲什么。。。。下面干货来了:重点重点重点,重要的事情说三遍。。。

    4、闭包的应用场景

    结论:闭包找到的是同一地址中父级函数中对应变量最终的值

    最终秘诀就这一句话,每个例子请自行带入这个结论!!!!!!!!!!!!!

    /* 例子1 */

    1 function funA(){
    2   var a = 10;  // funA的活动对象之中;
    3   return function(){   //匿名函数的活动对象;
    4         alert(a);
    5   }
    6 }
    7 var b = funA();
    8 b();  //10

    /* 例子2 */

     1 function outerFn(){
     2   var i = 0; 
     3   function innerFn(){
     4       i++;
     5       console.log(i);
     6   }
     7   return innerFn;
     8 }
     9 var inner = outerFn();  //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
    10 inner();
    11 inner();
    12 inner();
    13 var inner2 = outerFn();
    14 inner2();
    15 inner2();
    16 inner2();   //1 2 3 1 2 3


    /* 例子3*/

     1 var i = 0;
     2 function outerFn(){
     3   function innnerFn(){
     4        i++;
     5        console.log(i);
     6   }
     7   return innnerFn;
     8 }
     9 var inner1 = outerFn();
    10 var inner2 = outerFn();
    11 inner1();
    12 inner2();
    13 inner1();
    14 inner2();     //1 2 3 4

    /* 例子4*/

    1 function fn(){
    2     var a = 3;
    3     return function(){
    4         return  ++a;                                     
    5     }
    6 }
    7 alert(fn()());  //4
    8 alert(fn()());  //4

    /* 例子5*/

     1 unction outerFn(){
     2 var i = 0;
     3   function innnerFn(){
     4       i++;
     5       console.log(i);
     6   }
     7   return innnerFn;
     8 }
     9 var inner1 = outerFn();
    10 var inner2 = outerFn();
    11 inner1();
    12 inner2();
    13 inner1();
    14 inner2();    //1 1 2 2

    /*例子6*/

    1 (function() { 
    2   var m = 0; 
    3   function getM() { return m; } 
    4   function seta(val) { m = val; } 
    5   window.g = getM; 
    6   window.f = seta; 
    7 })(); 
    8 f(100);
    9 console.info(g());   //100  闭包找到的是同一地址中父级函数中对应变量最终的值

    /*例子7*/

    1 function a() { 
    2   var i = 0; 
    3   function b() { alert(++i); } 
    4   return b; 
    5 } 
    6 var c = a(); 
    7 c();      //1 
    8 c();      //2 

    /*例子8*/

     1 function f() { 
     2   var count = 0; 
     3   return  function() { 
     4       count++; 
     5       console.info(count); 
     6   } 
     7 } 
     8 var t1 = f();
     9 t1();     //1 
    10 t1();     //2 
    11 t1();     //3 

    /*例子9*/

     1 var add = function(x) { 
     2   var sum = 1; 
     3   var tmp = function(x) { 
     4       sum = sum + x; 
     5       return tmp;    
     6   } 
     7   tmp.toString = function() { 
     8       return sum; 
     9   }
    10   return tmp; 
    11 } 
    12 alert(add(1)(2)(3));     //6

    /*例子10*/

    1 var lis = document.getElementsByTagName("li");
    2 for(var i=0;i<lis.length;i++){
    3   (function(i){
    4       lis[i].onclick = function(){
    5            console.log(i);
    6       };
    7   })(i);       //事件处理函数中闭包的写法
    8 } 

    /*例子11*/

     1 function m1(){
     2      var x = 1;
     3      return function(){
     4           console.log(++x);
     5      }
     6 }
     7  
     8 m1()();   //2
     9 m1()();   //2
    10 m1()();   //2
    11  
    12 var m2 = m1();
    13 m2();   //2
    14 m2();   //3
    15 m2();   //4

    /*例子12*/

    1 var  fn=(function(){
    2    var  i=10;
    3    function  fn(){
    4       console.log(++i);
    5    }
    6    return   fn;
    7 })() 
    8 fn();   //11
    9 fn();   //12

    /*例子13*/

     1 function love1(){
     2      var num = 223;
     3      var me1 = function() {
     4            console.log(num);
     5      }
     6      num++;
     7      return me1;
     8 }
     9 var loveme1 = love1();
    10 loveme1();   //输出224

    /*例子14*/

     1 function fun(n,o) {
     2     console.log(o);
     3     return {
     4          fun:function(m) {
     5                return fun(m,n);
     6          }
     7     };
     8 }
     9 var a = fun(0);  //undefined
    10 a.fun(1);  //0  
    11 a.fun(2);  //0  
    12 a.fun(3);  //0  
    13 var b = fun(0).fun(1).fun(2).fun(3);   //undefined  0  1  2
    14 var c = fun(0).fun(1);  
    15 c.fun(2);  
    16 c.fun(3);  //undefined  0  1  1

    /*例子15*/

     1 function fn(){
     2    var arr = [];
     3    for(var i = 0;i < 5;i ++){
     4      arr[i] = function(){
     5          return i;
     6      }
     7    }
     8    return arr;
     9 }
    10 var list = fn();
    11 for(var i = 0,len = list.length;i < len ; i ++){
    12    console.log(list[i]());
    13 }  //5 5 5 5 5

    /*例子16*/

     1 function fn(){
     2   var arr = [];
     3   for(var i = 0;i < 5;i ++){
     4     arr[i] = (function(i){
     5         return function (){
     6             return i;
     7         };
     8     })(i);
     9   }
    10   return arr;
    11 }
    12 var list = fn();
    13 for(var i = 0,len = list.length;i < len ; i ++){
    14   console.log(list[i]());
    15 }  //0 1 2 3 4
  • 相关阅读:
    Angular Universal 学习笔记
    SAP Spartacus 如何获得当前渲染页面的 CMS 元数据
    Angular 服务器端渲染的学习笔记(二)
    Angular 服务器端渲染的学习笔记(一)
    第三方外部 Saas提供商如何跟使用 SAP 系统的客户进行对接接口集成
    如何从 SAP Spartacus Product Detail 页面,找到其 Angular 实现 Component 的位置
    具备自动刷新功能的 SAP ABAP ALV 报表
    C++学习目录
    c--条件编译
    c--文件读写--二进制
  • 原文地址:https://www.cnblogs.com/yuwenjing0727/p/13949333.html
Copyright © 2011-2022 走看看