什么是闭包?

有权访问另一个函数作用域内变量的函数都是闭包。

function a(){var n = 0;function inc() {n++;console.log(n);}inc();  inc();
}
a(); //控制台输出1,再输出2
//例子2
function a(){var n = 0;this.inc = function () {n++; console.log(n);};
}
var c = new a();
//console.log(c);
c.inc();    //控制台输出1
c.inc();    //控制台输出2

这里 inc 函数访问了构造函数 a 里面的变量 n,所以形成了一个闭包。

再看下一个例子:

function a(){var n = 0;function inc(){n++;        console.log(n);}return inc;
}
var c = a();
//console.log(c);
c();    //控制台输出1
c();    //控制台输出2

执行过程:

var c = a(),这一句 c()返回的是函数 inc,那这句等同于 var c = inc;

c(),这一句等同于 inc();  注意,函数名只是一个标识(指向函数的指针),而()才是执行函数。

后面三句翻译过来就是:  var c = inc;  inc();  inc();,跟第一段代码有区别吗? 没有。

为什么要这样写?

我们知道,js 的每个函数都是一个小黑屋,它可以获取外界信息,但是外界却无法直接看到里面的内容。将变量 n 放进小黑屋里,除了 inc 函数之外,没有其他办法能接触到变量 n,而且在函数 a 外定义同名的变量 n 也是互不影响的,这就是所谓的增强“封装性”。

而之所以要用 return 返回函数标识 inc,是因为在 a 函数外部无法直接调用 inc 函数,所以 return inc 与外部联系起来,例子 2 中的 this 也是将 inc 与外部联系起来而已。

再来思考一个问题:

function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(){return i;};}return result;
}
var funcs = createFunctions();
for (var i=0; i < funcs.length; i++){console.log(funcs[i]());
}

想想输出结果是什么?

tips函数带()才是执行函数! 单纯的一句 var f = function() { alert('Hi'); }; 是不会弹窗的,后面接一句 f(); 才会执行函数内部的代码。

//上面的代码可以解释成:var result = new Array(), i;
result[0] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
result[1] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
...
result[9] = function(){ return i; }; //没执行函数,函数内部不变,不能将函数内的i替换!
i = 10;
funcs = result;
result = null;console.log(i); // funcs[0]()就是执行 return i 语句,就是返回10
console.log(i); // funcs[1]()就是执行 return i 语句,就是返回10
...
console.log(i); // funcs[9]()就是执行 return i 语句,就是返回10

为什么垃圾回收了 result,但却不收了 i 呢? 因为 i 还在被 function 引用着啊。好比一个餐厅,盘子总是有限的,所以服务员会去巡台回收空盘子,但还装着菜的盘子他怎么敢收? 当然,你自己手动倒掉了盘子里面的菜(=null),那盘子就会被收走了,这就是所谓的内存回收机制

闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会徒增内存消耗!另外使用闭包也要注意变量的值是否符合你的要求,因为他就像一个静态私有变量一样。闭包通常会跟很多东西混搭起来,接触多了才能加深理解。

注明:

闭包存储的外部变量是「引用」而不是「值」,这样解释更加好一点。
for (var i=0; i < 10; i++){
  result[i] = function(){
    return i; //这里i存储的是「引用」而不是值,所以其「值」只有在执行时才能确定。
  };
}

javascript闭包案例一相关推荐

  1. JavaScript闭包详解及案例

    JavaScript闭包详解及案例 一. 变量作用域 函数内部可以使用全局变量 函数外部不可以使用局部变量 当函数执行完毕时,本作用域内的局部变量会被销毁 二. 闭包 闭包:有权访问另一个函数作用域中 ...

  2. [转载]深入理解JavaScript闭包(closure)

    最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...

  3. 深入理解JavaScript闭包(closure) 【收藏】

    深入理解JavaScript闭包(closure) 原文地址:http://www.felixwoo.com/archives/247  Felix Woo 最近在网上查阅了不少Javascript闭 ...

  4. 深入理解Javascript闭包

    收藏 最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开J ...

  5. 【转】深入理解JavaScript闭包(closure)

    文章来源:http://www.felixwoo.com/archives/247 最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说 ...

  6. (转)深入理解Javascript闭包(closure)

    深入理解Javascript闭包(closure) 一.什么是闭包?        "官方"的解释是:所谓"闭包",指的是一个拥有许多变量和绑定了这些变量的环境 ...

  7. 揭开Javascript闭包的真实面目

    揭开Javascript闭包的真实面目 闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分,本文将用通俗的语言带您深入理解Javascript闭包 ...

  8. Javascript闭包和闭包的几种写法及用途

    好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途.  一.什么 ...

  9. JavaScript学习总结(十六)——Javascript闭包(Closure)

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.很早就接触过闭包这个概念了,但是一直糊里糊涂的,没有能够弄明白JavaScript的闭包到底是什 ...

最新文章

  1. python list.pop 的方法的使用
  2. hibernate之 一级缓存和二级缓存
  3. python 读图片性能测试
  4. idea中build项目之后生成的target看不见
  5. Linux下获取毫秒级时间差
  6. Android Configuration change引发的问题及解决方法
  7. string数组批量转换成Int数组
  8. LeetCode 1722. 执行交换操作后的最小汉明距离(并查集)
  9. sharding-jdbc水平分库与垂直分库
  10. python 2.7安装某些包出现错误:libxml/xmlversion.h:没有那个文件或目录
  11. 21天学通C语言-学习笔记(4)
  12. oracle asm 加盘,ASM添加磁盘最佳实践
  13. 注册表--设置文件打开方式
  14. 计算机培训心得ppt展示,ppt制作学习心得
  15. 第六章 自然的数学化和分析化
  16. setcpu_SetCPU中文版
  17. Android自定义实现九宫格抽奖功能
  18. WES分析7-VCF
  19. 对Windows和类Unix争论的观点] 谁是谁的躯壳,谁又是谁的灵魂
  20. 5.8G传输设备替代方案(解决5.8G设备的抗干扰问题)5.8G点对点 点对多点无线网络

热门文章

  1. 次世代建模到底怎么学呢?怎样才能高薪入职,如何不走冤枉路
  2. Eclipse 调试jar包源码
  3. CC2640R2F工程之间相互转换
  4. 安全siem_当时和现在的安全相关性是关于siem的可悲事实
  5. C++之父名著——C++程序设计原理与实践 英文原版
  6. Vue中的 key 的作用是什么?
  7. 设计模式--生成器模式
  8. 网贷行业马太效应加剧,泰然金融稳居行业头部平台
  9. 2022云边协同大会 丨直播回放+PPT下载
  10. 基于three.js如何在模型加消息提示框?