简单了解Javascript中的闭包及常用场景

闭包的定义:

闭包是JavaScript中,函数的一种高级应用方式
在了解闭包之前,我们需要知道函数的定义作用域执行作用域

 function box(){
         function fn(){
         console.log("我是fn函数")
         }
         fn();
         // fn的执行作用域,是box的局部作用域
     }
    // box的定义作用域,是全局作用域
    // fn的定义作用域,是box的局部作用域

     box();
     // box的执行作用域,是全局作用域
     fn();   //执行不了

     function fun(){
         box();
         // box的执行作用域,是fun的局部作用域
     }

函数执行时会开辟一个执行空间, console.log(“我是fn函数”)这段代码就是在这个空间中执行,当代码执行完毕后,这个空间就被销毁了
然后我们再看下面的代码:

	function box(){
       	 function fn(){

       	 }
      	  return fn;
 	   }
	var f = box();
    f();
    // 当前变量f,其实就是box内部的fn,的执行作用域,就变成了全局

在box中返回了一个函数,返回值被变量f保存,因为函数也是对象,简单赋值属于浅拷贝,那么其实当前的f就是box中返回的那个函数的一个引用,如果将f作为函数执行了,相当于执行了box返回的那个函数的引用,其实就是执行了box里面的函数

总结:

函数的定义作用域,是固定的,写在哪就是哪
函数的执行作用域,是可变的,在哪执行就是哪
函数在执行时,可以拿到当前函数所在定义作用域中的所有数据

了解了以上的内容后,其实也就了解的闭包的大部分内容。我们再看下面两段代码,比较不同之处。

 function box(){
        var a = 10;
        a++;
        console.log(a);
    }
    box();  // 11
    box();  // 11
======================================    
    function box(){
        var a = 10;
        function fn(){
            a++;
            console.log(a);
        }
        return fn;
    }
    var f = box();
    f();	//11
    f();	//12

看到这里其实就已经产生了闭包,那么到底什么是闭包呢?

闭包:利用函数的嵌套,实现将第一层函数中的局部变量,可以在第一层函数外部修改的过程就叫闭包。

闭包的总结:

1.有一个函数A,在函数A内部返回一个函数B
2.在函数B中访问函数A的私有作用域变量即私有变量
(私有变量:函数内部的变量,在外部修改)
3.在函数A外部,有变量引用函数B

闭包并不是一种固定写法,而是一种场景,只要满足了以上三个条件,缺一不可,就是闭包

闭包的特点:

既是优点也是缺点
1.作用域空间不销毁
2.可以通过闭包语法,从外部访问函数内部的变量
3.保护私有变量
4.解决掉所有的全局变量,节省内存空间

我们也可以换种方式理解,闭包就好像是电脑上的回收站。
硬盘即存储空间,删除数据,先转到某个空间中(回收站),可以找回来
内存即运行空间,删除数据,直接删除,找不回来
闭包就是利用作用域的嵌套,触发计算机的垃圾回收机制让执行空间不销毁,提升函数作用域的生命周期。
闭包:就是利用作用域的嵌套,将局部变量进化成私有变量环境

最后我们再来看闭包的几个常用场景

闭包的应用场景:

1.循环中的事件,事件处理函数中使用了循环的每次的计数器

        var ali = document.querySelectorAll(".list li");
        for(var i=0;i<ali.length;i++){          
            ali[i].onclick = (function(index){
                return function(){
                    console.log(index);
                }
            })(i);
        }

2.给某些系统默认的回调函数,传参

       //给计时器的回调函数,传参
       function fn(a){
           return function(){
               console.log(a);
           };
       }
       setTimeout(fn("CSDN"), 1000);

3.模块化开发

        var f = (function(){
            var a = "hello";
            function fn(){
                console.log(a + "world");
            }
            return fn;
        })();
        f();
发布了7 篇原创文章 · 获赞 12 · 访问量 1428

猜你喜欢

转载自blog.csdn.net/fate_flower/article/details/104911587