美文网首页
浅谈闭包

浅谈闭包

作者: 枫尘逍遥 | 来源:发表于2017-11-28 16:36 被阅读0次

js中的闭包

闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包

什么是闭包

这个概念性的东西翻译有很多种,纯官方的翻译比较晦涩难懂,我们把它理解成一个比较特殊的函数就行。按照网上的说法来说就是:

「函数」和「函数内部能访问到的变量」(也叫环境)的总和,就是一个闭包。

function close(){

    varn=999;

    var getNumber=function(){

        return n;        

    };

    return getNumber;    

}

在close函数里面有一个getNumber方法,通过getNumber方法可以访问到函数的内部变量。

闭包的特性

能够读取函数内部的变量

能让这些变量的值始终保持在内存中

第一点很好理解,我们平时可能在不知不觉中就使用了闭包的这个特性,而第二点虽然用的不多,但是在面试中经常遇到。首先我们先看一段代码:

function f1(){

    varn=999;       

    nAdd=function(){

            n++;

        };

    function f2(){

        console.log(n);

        }

        return f2;

    }

var result=f1();

 result();//999

 nAdd();    

  result();//1000

为什么第二次执行后打印的结果是1000,而不是999,因为n被保存下来了,并没有被内存回收机制回收。

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

面试题解读

这是一个很常见的闭包面试题:

varresult=[ ];

function foo(){

    vari=0;for(;i<3;i=i+1){ 

           result[i]=function(){

                alert(i);

            } 

       }

    }

foo();   

result[0]( );// 3

result[1]( );// 3

result[2]( );// 3

运行结果为什么是3,我简单的重现一下代码运行的过程,

i=0;result[0]=function(){alert(i)};

i=1;result[1]=function(){alert(i)};

i=2;result[2]=function(){alert(i)};

运行的时候在function内部放的是一个变量i,只有被执行的时候才会给这个i赋值。当执行result[0]的时候,里面的变量i因为在当前作用域下并没有被定义,所以向它的父级去找,此时for循环已经执行完毕,i的值是3,所以弹出的都是3。为什么i保存下来了,因为result函数依赖于foo函数,所以foo一直在内存中,i变量也没有被内存回收机制回收。

那么如何实现弹出的是0,1,2呢?

利用之前提到的闭包就可以了,代码如下:

varresult=[ ];function foo(){

    var i=0;

    for(;i<3;i=i+1){ 

           (function(){

                var index=i;

                result[i]=function(){

                    alert(index); 

               }

            })() 

       }

    }

foo();   

result[0]();// 0

result[1]();// 1

result[2]();// 2

利用立即执行函数(IIF),我们可以创建一个闭包,在这个IIF内部,我们使用index将i给保存下来了。具体执行过程如下:

i=0;

(function(){

    var index=0;

    result[0]=function(){

        alert(index);

    }})()

i=1;

(function(){

    var index=1;

    result[1]=function(){

        alert(index);

    }})()

i=2;

(function(){

    varindex=2;

    result[2]=function(){

        alert(index);

    }})()

因为这些语句都放在IIF中,所以都有各自的作用域,index并不会重复。就像下方的代码:

var sayHi=function(){

    var words="hi"

}

var sayHello=function(){

    var words="hello"

}

两个方法中虽然都有words这个变量,但是因为在不同的函数中,都有各自的作用域,所以互不干扰。

参考文献

阮一峰:学习Javascript闭包(Closure)

相关文章

  • 浅谈闭包

    闭包是函数式语言里面很重要的部分,但是网上很多文章却只讲闭包的应用,而鲜有谈及其本质。 理解闭包的关键在于,知道它...

  • 浅谈闭包

    简要来讲,闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。 ...

  • 浅谈闭包

    前端开发者经常在面试时会碰到这样一道题:什么是闭包?首先我们来谈谈闭包的定义:函数A有内置函数B,当内置函数B调用...

  • 浅谈闭包

    js中的闭包 闭包是学习js中永远也绕不过去的一个坎,那么,今天我们就去一段简单的代码开始聊一聊闭包 什么是闭包 ...

  • 浅谈闭包

    《你不知道的JavaScript》这样描述: 当函数可以记住并访问所在的词法作用域时,就产生了闭包, 即使函数是在...

  • 浅谈闭包

    闭包是JavaScript的重点也是难点之一,由于涉及多重知识点,对初学者来说比较难理解。本文将闭包相关的知识点进...

  • 浅谈闭包

    注: 文章摘自 Reng の Blog 定义 闭包是指有权访问另一个函数作用域中的变量的函数 我的理解是,函数内的...

  • 闭包

    浅谈 python 的闭包思想 首先 python的闭包使用方法是:在方法A内添加方法B,然后return 方法B...

  • swift闭包

    浅谈闭包 闭包就是一段代码块,可以在任何地方调用。和函数类似,有参数和返回值。 来看一个简单的例子 带有参数的闭包...

  • 浅谈js闭包

    一.作用域 var x = 0 //全局变量 x var y = 10 //全局变量 y var fun...

网友评论

      本文标题:浅谈闭包

      本文链接:https://www.haomeiwen.com/subject/jcjebxtx.html