当前位置:首页 > 开发 > Web前端 > JavaScript > 正文

理解javascript闭包

发表于: 2015-11-13   作者:互联网   来源:转载   浏览次数:
摘要: 原文: 理解javascript闭包 1.闭包是什么 官方解释:闭包是一个拥有很多变量和绑定了这些变量的环境的表达式(其实就是函数),因而这些变量也是该表达式的一部分。这个定义虽然太学术,但是告诉我们两个信息: 1)闭包是一个函数 2)函数中有很多变量 上面两个是构成闭包的两个主要条件。 下面我们用通俗的话来解释一下:js中的所有函数都是闭包(因为函数中的局部变量只能函数内部访问
原文: 理解javascript闭包

1.闭包是什么

官方解释:闭包是一个拥有很多变量和绑定了这些变量的环境的表达式(其实就是函数),因而这些变量也是该表达式的一部分。这个定义虽然太学术,但是告诉我们两个信息:

1)闭包是一个函数

2)函数中有很多变量

上面两个是构成闭包的两个主要条件。

下面我们用通俗的话来解释一下:js中的所有函数都是闭包(因为函数中的局部变量只能函数内部访问),但是嵌套函数产生的闭包更加强大,也是我们现在所探讨的闭包。

如果上面的解释还不够通俗,下面的终极解释我想你一定能够看懂:

有一个函数a,函数a中嵌套了一个函数b,如果函数b被函数a外部的一个变量引用,就创建了一个闭包。

下面我们来看看具体如何通过代码来创建闭包,以加深上面概念的理解。

2.创建闭包

在创建闭包之前,首先要明白两个概念,一个是变量的作用域,一个事js中的作用域链,第一点我们简单说一下,第二点自己去查资料。

在Js中变量根据作用域的不同可以分为全局变量和局部变量(事实上很多语言都是这样),在js中,如果一个变量没有定义在任何函数中,则为全局变量;相对应的,定义在函数中的变量就是局部变量,但是如果函数中变量在声明时没有使用var关键字,则其仍然会称为全局变量。我们来看例子。

 

function f() {

            a = 1;//没有使用var,所以在函数外部也可以访问

        }

        f();

        alert(a);

  

下面我们看看如何创建闭包,看下面的函数

 

 

     function f1() {

            var a = 10;

            a++;

            alert(a);

        }

        var func1 = f1();

        func1;

        func1;

 

希望你能猜对上面代码的运行结果,只输出一个11。在函数f1的外部创建了变量func1,然后指向由函数f1的构造函数创建的对象。(在js中,你可以将函数看作是类,)。当执行完代码func1之后,这个对象就没有引用了,所以会被垃圾回收,对象中的变量a同样也会被回收;所以当再次执行func1时就不会有输出了。

 

从上面的代码,希望你能明白这样一个道理:js中是有垃圾回收机制的。当一个对象没有变量引用的时候,这个对象就会被回收。

再来看下面的代码:

 

function f1() {

            var a = 10;

            function f2() {

                a++;

                alert(a);

            }

            return f2;

        }

        var func1 = f1();

        func1();

        func1();

  

上面代码的输出结果为11,12。

 

执行完第一句func1()之后,对象应该被回收,第二句func1();应该没有输出猜对呢,这是为什么呢?

我们来分析一下。

首先看var func1=f1();这行代码执行之后,func1是什么。在函数f1中返回的是函数f2,所以func1的值其实是函数f2。按理说当执行完这行代码之后,函数f1的使命已经完成,应该被垃圾回收才是,你们变量a也会被清除,但是执行代码func1()之后的结果居然为11,这说明函数f1中的变量a没有被清除,那么肯定函数f1也没有被垃圾回收。这是为什么?

我们前面说过,一个对象如果被垃圾回收的条件是什么,那就是没有变量引用这个对象。我们来看看上面的代码。函数f2中对函数f1中的变量a进行++操作,也就是说在函数f2中引用了函数f1中的变量,也就是函数f2引用了函数f1。而代码var func1=f1();其实是将函数f2返回给变量func1,也就是说变量func1引用了函数f2,而函数f2由引用了函数f1,这种间接引用的结果就是函数f1一直被变量引用着,所以一直无法被垃圾回收。

上面的情况就是闭包,我们再回顾一下闭包的定义:如果函数a中的嵌套函数b被函数a外部的变量引用,就创建了闭包。

综合上面的讨论,我们可以看出闭包的作用是什么

3.闭包的作用

1)变量的安全性:我们无法在函数f1的外部直接访问其局部变量a,只能通过函数f2来访问,而在函数f2中我们可以写代码进行安全性的控制,这是不是和c#中类的属性很像。所以我们可以将函数f2看成是函数f1的一个属性,这个属性只有setter方法,而将局部变量a看成是函数f1的私有字段,只能通过公共属性f2才能访问f1中的私有字段a。

2)让变量的值始终保存在内存中。这个已经非常清晰了,通过闭包,函数f1中的变量a没有被回收,而是一直保存在内存中。

理解javascript闭包

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标 学好一门,学精通一门。不求
什么是闭包 闭包是指有权访问另一个函数作用域中的变量的函数(有点拗口吧),简单点就是在一个函数
五、闭包的微观世界 继续使用上篇的代码: function a() { var i = 0; function b() { alert(++i);
原文地址: http://coolshell.cn/articles/6731.html 前言:还是一篇入门文章。Javascript中有几个
作用域链与[[scope]] 通过调用 Function 构造函数创建的函数对象,其内部的 [[scope]] 属性引用的作
一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两
前面提到的上下文环境和作用域的知识,除了了解这些知识之外,还是理解闭包的基础。 至于“闭包”这
  好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了。好了,进入正题,今天来
原文: 全面理解Javascript闭包和闭包的几种写法及用途   好久没有写博客了,过了一个十一长假都变
全面理解Javascript闭包和闭包的几种写法及用途   好久没有写博客了,过了一个十一长假都变懒了,
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号