什么是闭包?闭包的优缺点?

闭包(closure)是javascript的一大难点,也是它的特色。很多高级应用都要依靠闭包来实现。

1、变量作用域

要理解闭包,首先要理解javascript的特殊的变量作用域。

变量的作用域无非就两种:全局变量和局部变量。

javascript语言的特别之处就在于:函数内部可以直接读取全局变量,但是在函数外部无法读取函数内部的局部变量。

注意点:在函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明的是一个全局变量!

2、如何从外部读取函数内部的局部变量?

出于种种原因,我们有时候需要获取到函数内部的局部变量。但是,上面已经说过了,正常情况下,这是办不到的!只有通过变通的方法才能实现。

那就是在函数内部,再定义一个函数。

function f1(){

    var n=999;

    function f2(){
      alert(n); // 999
    }

  }

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。

这就是Javascript语言特有的"链式作用域"结构(chain scope),

子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

3、闭包的概念

上面代码中的f2函数,就是闭包。

各种专业文献的闭包定义都非常抽象,我的理解是: 闭包就是能够读取其他函数内部变量的函数。

由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。

所以,在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

4、闭包的用途

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。

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

这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

5、使用闭包的注意点

(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

参考文献:

  学习Javascript闭包(Closure) - 阮一峰的网络日志

什么是闭包?闭包的优缺点? 1相关推荐

  1. 函数作为返回值练习 作用域和作用域链及预解析 闭包 闭包小案例

    函数作为返回值练习 <!DOCTYPE html> <html lang="en"> <head><meta charset=" ...

  2. 什么是闭包? 闭包有哪些优缺点?

    闭包(closure)指有权访问另一个函数作用域中变量的函数.简单理解就是 ,内部函数访问外部变量 优点: 延长变量作用域.在函数的外部可以访问函数内部的局部变量, 缺点: 容易造成内层泄露,因为闭包 ...

  3. 闭包--闭包作用之保护(一)

    闭包作用:保护 形成私有作用域,保护里面的私有变量不受外界干扰 例如多人协作开发:A的代码有fn(),B的代码有fn(),但是他们不相互影响 // A的代码<script>(functio ...

  4. [转][Python小记] 通俗的理解闭包 闭包能帮我们做什么?

    热身 首先给出闭包函数的必要条件: 闭包函数必须返回一个函数对象 闭包函数返回的那个函数必须引用外部变量(一般不能是全局变量),而返回的那个函数内部不一定要return 几个典型的闭包例子: # EN ...

  5. 32.Python面向对象(五)【描述符、运算符底层、装饰器:闭包-闭包参数-内置装饰器-类装饰器】

    目录: 每篇前言: Python面向对象(五) 1.1 描述符 1.2 运算符底层调用的什么? 1.3 装饰器 第一部分--引入门 (1)首先.咱再看遍闭包是啥: (2)然后,咱稍微高级点,看看闭包参 ...

  6. 作用域和闭包(闭包)

    闭包可以看做是把函数的词法作用域保存下来,以供在其他外部调用时能够做到访问权限的控制.参考如下代码: var fn; function foo() { var a = 2; function baz( ...

  7. JS闭包的作用与优缺点

    一.什么是闭包 闭包是指一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure). 简单来说就是指有权访 ...

  8. 什么是闭包?优缺点分别是什么?

    目录 1.举例子 2.什么是闭包? 3.闭包的优点 4.闭包的缺点以解决方法 5.闭包的两道经典题 1.举例子 最简单的两个闭包例子: // 闭包1(function(a){console.log(a ...

  9. go 变量在其中一个函数中赋值 另一个函数_go 学习笔记之仅仅需要一个示例就能讲清楚什么闭包...

    本篇文章是 Go 语言学习笔记之函数式编程系列文章的第二篇,上一篇介绍了函数基础,这一篇文章重点介绍函数的重要应用之一: 闭包 空谈误国,实干兴邦,以具体代码示例为基础讲解什么是闭包以及为什么需要闭包 ...

  10. 闭包函数 装饰器 迭代器

    闭包函数 一.什么是闭包 闭包:闭是封闭(函数内部函数),包是包含(该内部函数对外部作用域而非全局作用域的变量的引用).闭包指的是:函数内部函数对外部作用域而非全局作用域的引用.简单的说闭包函数就是把 ...

最新文章

  1. HTML实现跳转到页面指定位置
  2. Linux平台下 vimrc配置(转网友:http://blog.csdn.net/wooin/article/details/1887737)
  3. dropout理解(一)
  4. [JLOI2015]管道连接(斯坦纳树)
  5. 你单身,其实是个科学问题……
  6. [安卓] 19、一个蓝牙4.0安卓DEMO
  7. Python中的GIL锁
  8. raspberry pi_如何使用Raspberry Pi构建数字针Kong相机
  9. oracle 查询表里信息_oracle查询表信息
  10. JQ插件OrgChart实现组织结构图
  11. ENVI操作:监督分类
  12. 庄辰超:“去哪儿”的大生意
  13. c++ PDFium pdf转为图片
  14. WWW 2022 | 搜索广告CVR延迟反馈建模DEFUSE
  15. Vlan是什么?定义,特点超详细解析
  16. 生物信息学|Extracting Drug-Drug Interactions with Attention CNNs
  17. 计算机中的网络怎么共享的打印机驱动,如何共享打印机,如何设置打印机共享打印机共享设置图解-中关村在线...
  18. L1-030. 一帮一-PAT团体程序设计天梯赛GPLT
  19. WordCounter.icu - 一个简单的在线实时字数统计工具
  20. java知识串讲_java基础知识串讲

热门文章

  1. cocos3.4 使用quic-src报错:duplicate symbol _MD5_Final in:
  2. 比比网开源的一款头像制作小程序
  3. Libevent 学习七:Libevent 两个实例
  4. DBSCAN聚类算法简介
  5. linux安装cacti
  6. 【归并排序】基础代码
  7. t3软件怎么生成报表_t3财务报表怎么生成
  8. oracle同义词删除重建,Oracle同义词的创建与删除
  9. 【WebView】关于Android WebView 的一些坑
  10. 操作系统 - Linux