一、变量的作用域
要懂得闭包,起首必须懂得Javascript特别的变量作用域。
变量的作用域无非就是两种:全局变量和局部变量。
Javascript说话的特别之处,就在于函数内部可以直接读取全局变量。

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

Js代码
  function f1(){
    n=999;
    function f2(){
      alert(n);
    }
    return f2;
  }
  var result=f1();
  result(); // 999
--------------------------------------------------------------------------------------------------------
三、闭包的概念
上一节代码中的f2函数,就是闭包。
各类专业文献上的“闭包”(closure)定义很是抽象,很丢脸懂。我的懂得是,闭包就是可以或许读取其他函数内部变量的函数。
因为在Javascript说话中,只有函数内部的子函数才干读取局部变量,是以可以把闭包简单懂得成“定义在一个函数内部的函数”。
所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
--------------------------------------------------------------------------------------------------------b
四、闭包的用处
闭包可以用在很多处所。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终对峙在内存中。
怎么来懂得这句话呢?请看下面的代码。

Js代码
  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),这时必然要警惕,不要随便
改变父函数内部变量的值。

js的闭包概念的更多相关文章

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

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

  2. 关于js中闭包的理解

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

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

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

  4. 关于JS中闭包的问题

    一直以来,我都以为我已经懂了JavaScript中闭包的概念,直到有一次小伙伴突然问我这个概念的时候,我才发现我根本不知道该怎来么跟他来讲述这个概念. 那时候我就知道我是自我欺骗,打肿脸充胖子了. 所 ...

  5. js 理解闭包

    学习Javascript闭包(Closure) 引用: 阮一峰 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures. ...

  6. 我从没理解js的闭包,直到他人向我这么解释。。。

    前段时间根据执行上下文写过一次闭包,但是写的简陋些.昨天在twitter上看到这篇文章,感觉背包的比喻挺恰当的.所以就翻译了. 这篇文章有些啰嗦,但是讲解很细,希望还是耐心看完.也欢迎指出错误. 原地 ...

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

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

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

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

  9. [学习笔记]JS中闭包的理解

    一.闭包概念的理解 闭包,又称为词法闭包或函数闭包指引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外. 自由变量:该变量既不是函数本身定义的也不是函数 ...

随机推荐

  1. Sql Server系列:运算符和表达式

    运算符的一些符号,他们能够用于执行算术运算.字符串连接.赋值以及在字段.常量和变量之间进行比较.在SQL Server 2012中,运算符主要由以下6大类:算术运算符.赋值运算符.比较运算符.逻辑运算 ...

  2. 深入理解定时器系列第二篇——被誉为神器的requestAnimationFrame

    × 目录 [1]引入 [2]特点 [3]使用[4]兼容[5]应用 前面的话 与setTimeout和setInterval不同,requestAnimationFrame不需要设置时间间隔.这有什么好 ...

  3. codeforces Round #320 (Div. 2) C. A Problem about Polyline(数学) D. "Or" Game(暴力,数学)

    解题思路:就是求数 n 对应的二进制数中有多少个 1 #include <iostream> #include<cstdio> using namespace std; int ...

  4. 分享几个.NET WinForm开源组件,纪念逐渐远去的WinForm。。。

    前面3个月的时间内,这些.NET开源项目你知道吗?系列文章已经发表了3篇,共计45个平时接触比较少,曾经默默无闻的.NET开源项目,展示给大家,当然不是每个人都能用得上,但也的确是有些人用了,反响还不 ...

  5. 创建第二个 local network - 每天5分钟玩转 OpenStack(84)

    GUI 中有两个地方可以创建 network: 1. Project -> Network -> Networks 这是普通用户在自己的 tenant 中创建 network 的地方. 2 ...

  6. Web APi之手动实现JSONP或安装配置Cors跨域(七)

    前言 照理来说本节也应该讲Web API原理,目前已经探讨完了比较底层的Web API消息处理管道以及Web Host寄宿管道,接下来应该要触及控制器.Action方法,以及过滤器.模型绑定等等,想想 ...

  7. Android自定义spinner下拉框实现的实现

    一:前言 本人参考博客:http://blog.csdn.net/jdsjlzx/article/details/41316417 最近在弄一个下拉框,发现Android自带的很难实现我的功能,于是去 ...

  8. 初探nodeJS

    一.node概要 对nodeJS早有耳闻,但是一直迟迟没有对它下手,哈哈哈,今儿咱就来初探一下它. nodeJS是个啥东东? nodeJS,我的理解就是可以运行在后端的JavaScript. 为什么它 ...

  9. RESTful API URI 设计: 判断资源是否存在?

    相关的一篇文章:RESTful API URI 设计的一些总结. 问题场景:判断一个资源(Resources)是否存在,URI 该如何设计? 应用示例:判断 id 为 1 用户下,名称为 window ...

  10. java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍

    (原创,转载请说明出处!谢谢--http://www.cnblogs.com/linguanh/) 此文目的为了帮助大家较全面.通俗地了解线程 Thread 相关基础知识! 目录: --线程的创建: ...