您的位置:首页 > Web前端 > JavaScript

JavaScript系列_彻底理解闭包,如何彻底理解闭包,javascript中的闭包如何理解

2018-02-10 14:17 357 查看
导航:

一、概念
二、简单示例
三、
使用闭包的注意事项
四、闭包的示例

     说明一下:如果你对闭包的概念和简单使用会的话,那就可以直接看,第二大点的 第三步" 调用闭包(对闭包的深入理解,这个是重点"
详情:

一、 概念:

 官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。(函数就是一个表达式) 通俗的来说JavaScript中所有的function都是一个闭包。不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”。 什么是闭包:闭包是指在函数外部访问函数作用域中变量(局部变量)的函数;或者说闭包就是能够读取其他函数内部变量的函数;或者说闭包是指有权访问另一个函数作用域中的变量的函数;由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。

二、  简单示例:

a)  定义闭包

 function f1(){   var n =250;   functionf2(){//f2定义在f1的内部,可以读取f1的局部变量,f2是闭包;         n++;         alert(n);   }   returnf2;//返回f2的目的是外部可以调用f2函数,不至于,       因为,f2函数定义在f1内部,而导致外部不能调用。这样就相当      于f2还是可以在外部调用的。}

b)  调用闭包(简单调用)

       i. 第一步:调用f1(),把f()的返回值赋给f,f就是闭包函数f2。        var f = f1()//f就是f2。     ii. 第二步:调用f函数,也就是调用闭包函数f2f();//调用f,就是调用f2。

c)  调用闭包(对闭包的深入理解,这个是重点)

       i. 第一种调用法:var f = f1();f();//弹出251f();//弹出252;f();//弹出253解释:对于函数f2来说,变量n相当于是全局变量。由于闭包可以让该变量n一直保持在内存中,所以,每次调用f()时,都使用上次的值。     ii. 第二种调用法:1. f1()();//弹出251;2. f1()();//弹出251;3. f1()();//弹出251;解释:本以为第二种调法和第一种调法是同样的意思,但是,结果却令人惊讶。为什么?进一步解释:我们需要静下来心来,一定要静下心来,仔细人工执行这段代码。f1()()的执行过程:1)  执行第一个括号,f1()。调用f1函数,先执行代码var n = 250定义了一个变量n,再执行代码function f2(){alert(n);}定义一个函数f2,最后代码return f2 把函数f2返回2)  执行第二个括号f1()(),调用f2函数,执行n++,n的值从上一步的250变为251,并弹出n,即弹出了251。3)  当执行第二行的f()()时,还是重复上面两步:f1(),先调用函数f1,代码var n = 250定义了一个变量n,注意此处又重新定义了一个变量n,代码function f2(){alert(n);}定义一个函数f2,注意此处又重新定义了一个函数f2。f()()调用函数f2时,执行n++,n的值从前面的250变为251,并弹出n,即弹出了251。执行第三行的f()()时,是同样的道理,所以,注意:第二段代码f1()(),每次都会把f1先调用一次,而第一段代码只调用了一次f1。


 三、  使用闭包的注意事项

a)    由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。b)     闭包会在父函数外部改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

四、  闭包的示例:

a)    循环里包含匿名函数(没有自我运行)function test1(){   var arr = [];   for(var i=0; i<5; i++){             arr[i] = function(){                     returni;             };//这个把函数对象赋给了数组的每个元素;   }   return arr;}let arr =test1();//arr是五个函数arr[0]();//调用第一个函数 b)    循环里包含匿名函数(自我运行)function test2(){   var arr = [];   for(var i=0; i<5; i++){             arr[i] = (function(){                             return i;                      })();//自运行函数,把匿名函数的执行结果赋给了数组的元素,这是函数的调用   }   return arr;//数组里分别保存了 0,1,2,3,4 } c) 用闭包的方式实现mult(5)(6)(7),表示三个数的乘法(5*6*7)解答:先求mult(5)(6);再求mult(5)(6)(7),完成需求时,一定要学会拆分。第一步:完成mult(5)(6)function mult(m){       return function (n){            return m*n;   }}console.log(mult(5)(6)); 第二步:完成mult(5)(6)(7)function mult(m){       return function (n){            return function(k){                     return m*n*k;            };   }}console.log(mult(5)(6)(7));
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 闭包