/*一、变量的作用域
要理解闭包,首先必须理解Javascript特殊的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。*/

  var n=999;
  function f1(){
    alert(n);
  }
  f1(); // 999
//另一方面,在函数外部自然无法读取函数内的局部变量。
  function f1(){
    var n=999;
  }
  alert(n); // error
//这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
  function f1(){
    n=999;
  }
  f1();
  alert(n); // 999
/*--------------------------------------------------------------------------------------------------------*/
/*二、如何从外部读取局部变量?
出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。
那就是在函数的内部,再定义一个函数。*/
  function f1(){
    n=999;
    function f2(){
      alert(n); // 999
    }
  }
/*在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构(chain scope),
子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!*/

  function f1(){
    n=999;
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
/*--------------------------------------------------------------------------------------------------------*/
/*三、闭包的概念
上一节代码中的f2函数,就是闭包。
各种专业文献上的“闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。*/

/*四、闭包的用途
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
怎么来理解这句话呢?请看下面的代码。*/

  function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000
/*在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个
匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。*/
/*--------------------------------------------------------------------------------------------------------*/
/*五、使用闭包的注意点
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便
改变父函数内部变量的值。*/
/*--------------------------------------------------------------------------------------------------------*/
/*六、思考题
如果你能理解下面代码的运行结果,应该就算理解闭包的运行机制了。 */
var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
    return function(){
      return this.name;
   };
  }
};
alert(object.getNameFunc()()); //The Window

/*object.getNameFunc() 返回
function(){
return this.name
} 此时的this 指向的是window*/

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function(){
var _this = this;
    return function(){
      return _this.name;
   };
  }
};
alert(object.getNameFunc()()); //My Object

JS Closure 闭包的更多相关文章

  1. 彻底搞清js中闭包(Closure)的概念

    js中闭包这个概念对于初学js的同学来说, 会比较陌生, 有些难以理解, 理解起来非常模糊. 今天就和大家一起来探讨一下这个玩意. 相信大家在看完后, 心中的迷惑会迎然而解. 闭包概念: 闭包就是有权 ...

  2. 关于js中闭包的理解

    1.以前很不理解js中闭包的概念及使用,下面来看一下 function foo() { var a = 123; var b = 456; return function () { return a; ...

  3. js的闭包

    一,关于js闭包的只是感觉很高大上似乎,对于学弱来说任何问题都是这样的,值得去钻研和提高. 资料上理解的都是关于js的闭包其实就是js的变量的作用域的灵活使用. 函数内部定义变量的时候,一定要用 va ...

  4. iOS - Swift Closure 闭包

    1.Closure 闭包在 Swift 中非常有用.通俗的解释就是一个 Int 类型里存储着一个整数,一个 String 类型包含着一串字符,同样,闭包是一个包含着函数的类型.有了闭包,你就可以处理很 ...

  5. 理解运用JS的闭包、高阶函数、柯里化

    JS的闭包,是一个谈论得比较多的话题了,不过细细想来,有些人还是理不清闭包的概念定义以及相关的特性. 这里就整理一些,做个总结. 一.闭包 1. 闭包的概念 闭包与执行上下文.环境.作用域息息相关 执 ...

  6. JS的闭包、高阶函数、柯里化

    本文原链接:https://cloud.tencent.com/developer/article/1326958 https://cloud.tencent.com/developer/articl ...

  7. 关于js的闭包和复制对象

    一.有关js的闭包 1.概念:所谓的闭包,就是指的两个作用域,其中内层作用于可以访问外层作用域的函数的现象 2.简单应用 for(var i = 0;i< lis.lenth;i++){ (fu ...

  8. JS的闭包问题

    1.什么是“闭包” 是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 2.闭包的应用场景 (1)保护变量的安全实现JS私有属性和私有方法 (2)在 ...

  9. 三个JS函数闭包(closure)例子

    闭包是JS较难分辨的一个概念,我只是按自己的理解写下来,如有不对还请指出. 函数闭包是指当一个函数被定义在另一个函数内部时,这个内部函数使用到的变量会被封闭起来形成一个闭包,这些变量会保持形成闭包时设 ...

随机推荐

  1. python 绘图库 Matplotlib

    matplotlib官方文档 使用Matplotlib,能够轻易生成各种图像,例如:直方图.波谱图.条形图.散点图等. 入门代码实例 import matplotlib.pyplot as plt i ...

  2. USB驱动程序之USB设备驱动程序2鼠标用作键盘学习笔记

    1.usbmouse.c (1)probe函数 在这个probe函数后判断是不是一个鼠标,先得到usb_host_interface结构体,除了端点0外,端点个数如果不是1,返回错误,表示不是自己能支 ...

  3. 使用Eclipse可以启动服务器,却不能访问localhost

    今天心血来潮修改了Tomcat的端口号,将默认的8080改为8888,使用MyEclipse部署项目没有问题,只是访问的地址不可以使用8080而是要用8888,这是当然的了,毕竟我修改了.但是使用Ec ...

  4. 使用国内源部署ceph

    由于网络方面的原因,Ceph的部署经常受到干扰,通常为了加速部署,基本上大家都是将Ceph的源同步到本地进行安装.根据Ceph中国社区的统计,当前已经有国内的网站定期将Ceph安装源同步,极大的方便了 ...

  5. DDoS攻防战 (四):CC攻击防御系统部署

    1. 系统效果 此DDOS应用层防御系统已经部署在了http://www.yfdc.org网站上(如果访问失败,请直接访问位于国内的服务器http://121.42.45.55进行在线测试). 此防御 ...

  6. 如何创建dll以及使用

    使用dll的好处: 隐藏了代码,公开了功能. 在VS2017中,创建一个DLL工程项目,将你的代码写入.cpp文件中,然后比如  这样: //////////// test.cpp #include ...

  7. Django 使用体会

    最近急于赶项目,少有更新博文.如今项目大致不那么赶了,终于可以在晚上码字码文章,而不是码代码了. 从开始使用Django开发到现在, 也已经有大半年了.公司的项目也是逐步地加功能,加模块,一步步完善设 ...

  8. 解决 Android Studio 报SDK tools directory is missing

    问题描述: 因为之前已经有安装过sdk manager,在设置中将Android SDK Location设置为Android SDK安装的目录之后还是一直报SDK tools directory i ...

  9. CyclicBarrier的使用

    最近一直整并发这块东西,顺便写点Java并发的例子,给大家做个分享,也强化下自己记忆,如果有什么错误或者不当的地方,欢迎大家斧正. CyclicBarrier是一种多线程并发控制实用工具,和Count ...

  10. css readonly和disabled的区别

    一.前言 要说readonly和disabled的区别,就需要先说说两者的联系: 两个属性都可以作用于input等表单元素上,都使得元素成为“不可用”的状态: 两者的字面意义先介绍一下: readon ...