javascript闭包案例一
什么是闭包?
有权访问另一个函数作用域内变量的函数都是闭包。
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闭包案例一相关推荐
- JavaScript闭包详解及案例
JavaScript闭包详解及案例 一. 变量作用域 函数内部可以使用全局变量 函数外部不可以使用局部变量 当函数执行完毕时,本作用域内的局部变量会被销毁 二. 闭包 闭包:有权访问另一个函数作用域中 ...
- [转载]深入理解JavaScript闭包(closure)
最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...
- 深入理解JavaScript闭包(closure) 【收藏】
深入理解JavaScript闭包(closure) 原文地址:http://www.felixwoo.com/archives/247 Felix Woo 最近在网上查阅了不少Javascript闭 ...
- 深入理解Javascript闭包
收藏 最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开J ...
- 【转】深入理解JavaScript闭包(closure)
文章来源:http://www.felixwoo.com/archives/247 最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说 ...
- (转)深入理解Javascript闭包(closure)
深入理解Javascript闭包(closure) 一.什么是闭包? "官方"的解释是:所谓"闭包",指的是一个拥有许多变量和绑定了这些变量的环境 ...
- 揭开Javascript闭包的真实面目
揭开Javascript闭包的真实面目 闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分,本文将用通俗的语言带您深入理解Javascript闭包 ...
- Javascript闭包和闭包的几种写法及用途
好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途. 一.什么 ...
- JavaScript学习总结(十六)——Javascript闭包(Closure)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.很早就接触过闭包这个概念了,但是一直糊里糊涂的,没有能够弄明白JavaScript的闭包到底是什 ...
最新文章
- python list.pop 的方法的使用
- hibernate之 一级缓存和二级缓存
- python 读图片性能测试
- idea中build项目之后生成的target看不见
- Linux下获取毫秒级时间差
- Android Configuration change引发的问题及解决方法
- string数组批量转换成Int数组
- LeetCode 1722. 执行交换操作后的最小汉明距离(并查集)
- sharding-jdbc水平分库与垂直分库
- python 2.7安装某些包出现错误:libxml/xmlversion.h:没有那个文件或目录
- 21天学通C语言-学习笔记(4)
- oracle asm 加盘,ASM添加磁盘最佳实践
- 注册表--设置文件打开方式
- 计算机培训心得ppt展示,ppt制作学习心得
- 第六章 自然的数学化和分析化
- setcpu_SetCPU中文版
- Android自定义实现九宫格抽奖功能
- WES分析7-VCF
- 对Windows和类Unix争论的观点] 谁是谁的躯壳,谁又是谁的灵魂
- 5.8G传输设备替代方案(解决5.8G设备的抗干扰问题)5.8G点对点 点对多点无线网络