为什么要用闭包(closure)?

前言

闭包(closure)这个词是在学习JavaScript过程中经常被提到的,很多人一开始都对此有些迷惑,然后在不断地参考学习中逐渐掌握,本文主要简述下自己学习过程中对闭包的理解。

什么是闭包?

MDN官方解释:

Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.

closure是拥有独立变量(在封闭空间中定义的可以在本地环境中使用的变量)的函数,换句话说,就是这种函数可以"记住"他们创建的环境。
简而言之,就是闭包是一个函数,能将创建的变量的值始终保持在内存中,以供本地环境使用。

为什么要用闭包?

说到这里就不得不提下JavaScript的变量作用域问题。变量作用域无非就两种:全局作用域和局部作用域。
在JavaScript(特指ECMAScript5前的版本)语言中具有作用域的仅有函数function。并且有个特点就是:函数内部可以直接访问外部变量,但在函数外部无法访问函数内部变量。这也就是Javascript语言特有的“链式作用域”结构(chain scope)。
那么我要是想在函数外部访问函数内部变量怎么办?所以闭包就出现了,简单说,我们使用闭包的主要作用就是间接访问函数的内部数据。

怎么创建闭包?

理解了JavaScript的作用域局限以及为什么需要使用闭包之后,我们就可以动手解决这一问题。下面用一个简单例子来详细说明这一过程:

  1. 首先我们来看下要解决的问题:
 var num = 12;
 function showNum() {
     console.log(num);
 }
showNum();//12

在上面代码中执行函数showNum(),因为函数内部可以访问外部变量num,所以执行结果为12.

function showNum() {
     var num = 12;  //此处注意要使用var声明,否者等于直接声明全局变量num
  }
 console.log(num);//Uncaught ReferenceError: num is not defined

由于函数外部不能够访问函数内部变量,所以直接访问输出num时,由于此时num并未定义,故抛出错误信息。那么如何获取函数内部变量呢?

  1. 在函数内部再定义一个内部函数,并将这个内部函数当做返回值,这样我们就可以获取函数的局部变量。
 function showNum() {
      var num = 12;
      function showNum2() {
           console.log(num);
      };
      return showNum2;
  }
var myNum = showNum();
myNum();//12

在上面的代码中,在函数showNum中嵌套一层函数showNum2,由于内层函数可以访问外层函数的变量,所以,执行showNum()函数时,showNum2函数可以直接读取外层函数showNum()的局部变量num的值,并输出12。
以上实现了闭包的主要作用之一:读取函数内部变量

  1. 那么闭包还有什么作用呢?
    还记得文章开头引用的MDN的解释吗:

Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.
//将创建的变量的值始终保持在内存中,以供本地环境使用

是的,这也是闭包的作用之一,如下例子:

 function showNum() {
      var num = 12;
      function showNum2() {
           console.log(++num);
      };
      return showNum2;
  }
var myNum = showNum();
myNum();//13

一般情况下在函数被调用完后不再被引用时,该函数都会被垃圾回收机制(garbage collection),但是由于上述代码中函数showNum2被myNum引用,而函数showNum2又依赖于函数showNum,因此函数showNum不会被垃圾回收机制回收。

以上只是目前学习中的一些总结整理,对其原理性认识还完全达不到全面,后续会继续了解完善。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容