`

我对Javascript闭包的理解

阅读更多

我对Javascript闭包的理解

 

      关于闭包是什么,这个问题困扰了我很久。我好像知道是什么,但好想又说不清楚。今天,我查阅了相关的资料,把自己的一些理解记录在此,以备他日有用。

“闭包”这个词,我不知道是谁翻译的,我个人感觉,这个翻译真的是误导了不少中国程序员。

     本人呢,也曾经幼稚的以为“闭包”就是“Close package”。对比了《Javascript权威指南》中文和英文版本,我才知道我们所说的闭包,人家洋大哥叫做“Function Scope and Closures”(这个见《Javascript Definitive Guide》第八章8.8节)。《JavaScript: The Good Parts》(《Javascript语言精粹》)第四章 4.10 叫做Closures。

     从上面的描述,我想大家已经知道闭包的字面意思,“一个封闭的函数作用域”。此话怎讲?就是说在一个闭包内声明的变量,只有在这个闭包内定义的函数才能访问。 说了这么多,不知道看的人迷糊没,反正我是迷糊了。迷糊了咋办,写个例子理解一下。

我们有一个函数,名字比方说叫做tmd(虽然这个名字不好听,但是我想不出一个更合适的了,凑合用吧)。这个函数是干什么用的呢?你想干什么就干什么。

function tmd(){

    //在这儿你可以随便写你想些的代码,我无所谓。

}

 

现在有个想法,就是我想知道tmd这个函数被调用了多少次?

这活好干啊,声明个全部变量tmdNum,每次调用tmd的时候+1不就搞定了。

var tmdNum = 0;

function tmd(){

    //在这儿你可以随便写你想些的代码,我无所谓。

      tmdNum ++;

      alert(tmdNum);

}

现在很好,代码运行正常,也能完成我们的需求。

 

话说在一个阳光明媚的下午,本人正在喝着咖啡和MM聊天呢,同事告诉我说tmd这个方法呗调用了3000多次。本人听完脑袋都大了,谁这么脑残也不能在一个页面里一个方法调3000多次啊。经过一段痛苦的查找,在我那个亲爱的搭档的代码里面发现了这么一句:

  tmdNum = 3000;

看来全局变量是不能用了,太不安全了。怎么办,用闭包。

var tmd = function(){//这里我们叫做"匿名函数1"

    var tmdNum = 0;

    return function(){//这里我们叫做"匿名函数2”

        //在这儿你可以随便写你想些的代码,我无所谓。

         tmdNum ++;

         alert(tmdNum);

    }

 

}(); //千万要注意这里的这个小括号。

这段代码什么意思呢?

第一步:先把函数里面的内容都删了,看总体的结构

var tmd = function(){}();

这行代码的意思是 先声明一个变量,变量的名字叫做tmd。

function(){} 这是声明了一个匿名函数

function(){}(); 加个括号的意思是让这个匿名函数立即执行。

所以,tmd的值就是这个匿名函数的返回值。如果这个函数什么也不返回,tmd的值就是undefined。

 

第二步:看匿名函数里面的内容

匿名函数里面有做了两件事情

一是什么了一个变量tmdNum,并赋初值为0;

二是执行一个return,return function(){} 表示返回的是一个函数。这个函数的函数体执行的步骤跟我们文章一开始写的那个tmd函数的执行步骤是一样的。

 

结果:我们折腾了这么一大圈,达到的目的是什么呢。首先,匿名函数1 return了一个函数(匿名函数2)赋给了tmd变量。这样调用tmd(),实际调用的就是匿名函数2。因为tmdNum这个变量只能被匿名函数2调用,所以最终的效果就是tmdNum这个变量只能在tmd()调用的时候改变。

 

从此,互不干涉,天下太平。(以上故事纯属扯淡,扯扯更健康!)

 

这里我摘抄了《Javascript设计模式》里面的一段话,补充下关于闭包的问题:

闭包(closure)是一个受到保护的变量空间,由内嵌函数生成。

Javascript具有函数级别的作用域。这意味着定义在函数内的变量不能在函数外部被访问。

Javascript的作用域又是词法性质的(lexically scoped)。这意味着函数运行在定义它的作用域中,而不是调用它的作用域中。把这两个因素结合起来,就能通过把变量包裹在匿名函数中而对其加以保护。

这里要注意的一点是:

Javascript的作用域是函数范围的,在Java等语言中

public void fun(){

     int i = 3;

     if(i > 0){

           int b  = 0;

     }else{

           int b  = 1;

     }

     //System.out.println(b);

     //Java语言里面,在这里b是不能访问的。因为b的作用域在大括号内。

}

Javascript中,情况不一样:

function fun(){

     var i = 3;

     if(i > 0){

           var b  = 0;

     }else{

           var b  = 1;

     }

     alert(b);

     //Javascript中,这里访问b是没有问题的,因为Javascript中,作用域是函数范围内的。

}

 

分享到:
评论

相关推荐

    javascript闭包的理解

    标题《JavaScript闭包的理解》涉及的知识点主要围绕JavaScript编程中的一个重要概念——闭包。闭包是一个高级且复杂的话题,它是JavaScript语言的核心特性之一,同时也是一大难点。要想熟练运用JavaScript,掌握闭包...

    JavaScript闭包

    Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态...本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。

    javaScript闭包的理解

    ### JavaScript闭包的理解 #### 一、闭包的定义与特点 闭包是JavaScript中一个非常重要的概念,它指的是一个函数能够访问并操作其外部作用域中的变量的能力。这一特性使得JavaScript具有了一些其他语言不具备的...

    理解_JavaScript_闭包

    本文结合 ECMA 262 规范详解了闭包的内部工作机制,让 JavaScript 编程人员对闭包的理解从“嵌套的函数”深入到“标识符解析、执行环境和作用域链”等等 JavaScript 对象背后的运行机制当中,真正领会到闭包的实质。

    深入理解javascript原型和闭包

    深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系

    javascript闭包详解中文word版

    本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAscript语言规范来使读者可以更深入的理解闭包。闭包是Closure, 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    Javascript 闭包完整解释

    ### JavaScript闭包完整解释 #### 一、闭包的基本概念 **闭包**是一个非常重要的JavaScript概念,它指的是一个函数能够记住并访问其外部作用域中的变量的能力,即使该函数在其外部作用域之外被调用也是如此。具体...

    JavaScript闭包深入理解.pdf

    总的来说,闭包是JavaScript中实现某些高级功能的关键,它允许函数保留对定义时环境的引用,从而创建持久化的状态。理解闭包对于编写高效、健壮的JavaScript代码至关重要。通过不断实践和深入学习,开发者可以更好地...

    JavaScript对闭包的理解.md

    为了帮助大家快速和较好地理解JavaScript函数中的闭包,本文对JavaScript的闭包进行了分析并进行简易的代码演示,希望本文能够给有需要的人带来一点小小的帮助。

    跟我学习javascript的闭包

    陆陆续续接触了一些闭包的知识,也犯过几次因为不理解闭包导致的错误,一年多了资料也看了一些,但还是不是非常明白,最近偶然看了一下 jQuery基础教程 的附录,发现附录A对JavaScript的闭包的介绍简单易懂,于是...

    JavaScript闭包函数

    闭包是ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下...

    js闭包个人理解

    ### JavaScript闭包的理解 在JavaScript中,闭包(Closure)是一种非常重要的概念,它涉及到函数作用域、变量生命周期以及函数内部对外部作用域的访问等多个方面。...希望本文能对你理解JavaScript闭包有所帮助。

    深入理解_JavaScript_闭包

    总之,深入理解JavaScript闭包对于编写高效、可维护的代码至关重要。掌握闭包不仅有助于解决实际问题,还能提高编程技巧和对JavaScript语言机制的理解。在日常开发中,无论是用于实现模块化、数据封装,还是处理异步...

    javascript 闭包实例下载

    JavaScript 闭包是一种高级编程概念,它在JavaScript中扮演着至关重要的角色,特别是在函数式编程和模块化设计中。闭包本质上是函数和其能够访问...通过学习这些实例,你将能够更好地掌握JavaScript闭包这一核心概念。

    JavaScript知识点总结(十六)之Javascript闭包(Closure)代码详解

    总之,JavaScript闭包是理解和掌握JavaScript高级特性的重要基础,它允许开发者创造出更为灵活和功能强大的代码结构。通过学习闭包的原理和应用,开发者可以更好地控制函数执行的上下文环境,以及更有效地管理变量的...

    基于javascript 闭包基础分享

    理解闭包的关键在于理解JavaScript的作用域规则。在实际应用中,闭包是JavaScript工程师必须掌握的概念。尽管闭包提供了强大的功能,但在某些情况下也可能会导致内存泄漏,特别是在旧版浏览器中的JavaScript引擎可能...

    javaScript闭包技术资料

    ### JavaScript闭包技术详解 #### 一、闭包的基本概念 **闭包**是JavaScript中一个重要的概念,它涉及到函数的执行环境、作用域链等关键要素。简单来说,闭包是一个函数及其相关的引用环境的组合。具体而言,当一...

    javascript闭包高级教程

    ### JavaScript闭包高级教程 #### 简介 在JavaScript编程中,“闭包”是一个非常重要的概念,尤其对于希望深入理解和高效使用JavaScript的开发者来说。简单地说,闭包是一种能够记住并访问其创建时周围环境的函数...

Global site tag (gtag.js) - Google Analytics