谈谈Javascript闭包
闭包意味着子函数在其父函数结束后,仍能调用其父函数的变量。
先看以下两个事例,来了解一下闭包的创建:
<script type="text/javascript"> //ex01 var mess = "我是最原始的信息"; setTimeout(function(){document.writeln(mess+"<br/>")},1000); mess = "我是修改后的信息"; setTimeout(function(){document.writeln(mess+"<br/>")},1000); //ex02 function delayedShow(message,time){ setTimeout(function(){ document.writeln(message+"<br/>"); },1000) } var message = "我是最原始的信息"; delayedShow(message,1000); message = "我是修改后的信息"; delayedShow(message,1000); </script>
ex01输出的结果为:我是修改后的信息 我是修改后的信息
ex02输出的结果为: 我是最原始的信息 我是修改后的信息
我们来分析一下,第一个事例比较简单,第一次调用函数之后1秒钟后进行setTimeout回调,setTimeout回调的function始终指向一个全局变量,mess。在setTimeout的方法还未被执行之前,mess已经被改变,所以两次输出的都是 “我是修改后的信息”。第二个实例就用到了闭包,当我们调用delayedShow的时候,实际上已经得到了setTimeout的回调函数的引用,让其在1秒钟后执行。在一个函数的子函数被外部引用时,就产生了闭包。也就是说,在一个函数的子函数被外部引用时,就产生了一个环境,在这个环境里面,所使用的变量都是独立的。在第一次调用delayedShow(message,1000)时,产生了一个环境,就是闭包结构,在这个环境里面,message的值为“我是最原始的信息”。第二次调用delayedShow(message,1000)时,又产生了一个环境,在这个环境里面message的值为“我是修改后的信息”。举个例子来说,一个函数嵌套一个子函数可以相当于一个面包屋(父函数)里面有一个面包机(子函数)。由于函数可以被重复调用,所以我们姑且假设这个面包屋可以被无限克隆。当外部派一个奶油面包师傅(参数)来经营这个面包屋的时候,这个面包师傅就克隆了一个面包屋,这个面包屋只卖奶油面包,掌管面包机的是奶油面包师傅。当外部派一个肉松面包师傅来经营这个面包屋的时候,这个肉松面包也克隆了一个面包屋,这个面包屋的内部结构跟奶油面包屋是一模一样的,只不过它只卖肉松面包,掌管面包机的是肉松面包师傅。依些内推。这里产生的每一个面包屋都叫一个闭包。
好了,我们再来看一个例子。
在我们平时的编码时,常常会碰到这么一个问题。先看代码,这段代码的本意是要点击一个按钮时分别弹出提示框,告诉用户其点击了哪个按钮
<input type="button" value="Button 1" id="btn1">
<input type="button" value="Button 2" id="btn2">
<input type="button" value="Button 3" id="btn3"> <script type="text/javascript"> function createEventHandlers(){ var btn; for(var i=1; i <= 3; i++){ btn = document.getElementById('btn' + i); btn.onclick = function(){ alert('Clicked button #' + i); } } } createEventHandlers();
</script>
这个代码在输出时,会弹出三个 Clicked button#3。代码似乎写得没错,一个简单的for循环。好吧,我们再看一个代码:
function createEventHandlers(){ var btn; for(var i=1; i <= 3; i++){ btn = document.getElementById('btn' + i); btn.onclick = createOneHandler(i); }
} function createOneHandler(number){ return function() { alert('Clicked button #' + number); }
}
咦,这段代码输出时分别会弹出Clicked button #1 Clicked button #2 Clicked button #3,为什么把函数独立出来就对了呢?
我们来改造一下上面两段代码,把for循环解开来写
<script type="text/javascript"> //ex01 var i = 1; click1 = function() { document.writeln("click button"+i); } i = 2; click2 = function(){ document.writeln("click button"+i); } i = 3; click3 = function (){ document.writeln("click button"+i); } //点击第一个按钮 click1(); //点击第二个按钮 click2(); //点击第三个按钮 click3(); //ex02 click5=function(k){ return function(){ document.writeln("click button"+k); } } var j = 1; bclick1=click5(j); j = 2; bclick2=click5(j); j = 3; bclick3=click5(j); bclick1(); bclick2(); bclick3(); </script>
看到这个,明白了吧,跟第一个例子一样,第一个写法中呢,函数依赖的是一个全局变量。第二个例子呢,我们使用闭包保存了变量。
另外,还有一个js编程中常常会碰到的问题也可以依靠闭包来解决。在编写js代码时,我们常常会将许多变量放在全局区域,这是一个糟糕的实践。原因呢,当然是因为它会干涉到其它代码库的运行,从而产生一些令人迷惑的问题。使用一个自动生效的匿名函数闭包可以从本质上将全局变量隐藏起来,不让其干涉到其它的库。
看例子:
// 利用包装器来创建一个匿名函数
(function(){
// 在这变量在这个包装器内是一个全局变量
var msg = "Thanks for visiting!";
// 将一个方法绑定到全局变量上
window.onunload = function(){
// 这里使用“被隐藏”起来的全局变量
alert( msg );
};
// 关闭匿名函数并且执行它
})();
这样子,我们就可以把利用到的变量与其它库隔离开来。(function(){})()中最后面的()是代表立即执行这个function。我们可以把代码这样改写,可以理解()的意义。
var f = function(){
var msg = "Thanks for visiting!";
window.onunload = function(){
alert( msg );
};
};
f();
个人博客地址:http://www.heymemory.com/blog/9/
转载于:https://www.cnblogs.com/xiaoruoen/archive/2011/09/23/2185832.html
谈谈Javascript闭包相关推荐
- JavaScript -- 闭包与作用域链
目录 什么是闭包 作用域及作用域链 闭包的使用及作用 闭包的作用: 闭包不会产生内存泄漏: 闭包的应用: 闭包练习题 参考文章: 什么是闭包 红宝书上解释: 闭包 是指有权访问另外一个函数作用域中的变 ...
- Javascript闭包和闭包的几种写法及用途
好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途. 一.什么 ...
- JavaScript学习总结(十六)——Javascript闭包(Closure)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.很早就接触过闭包这个概念了,但是一直糊里糊涂的,没有能够弄明白JavaScript的闭包到底是什 ...
- 全面理解Javascript闭包和闭包的几种写法及用途【转】
一.什么是闭包和闭包的几种写法和用法 1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. ...
- 全面理解Javascript闭包和闭包的几种写法及用途
一.什么是闭包和闭包的几种写法和用法 1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. ...
- JavaScript闭包如何工作?
您将如何向了解其闭包概念(例如函数,变量等)的人解释JavaScript闭包,但却不了解闭包本身? 我已经在Wikipedia上看到了Scheme示例 ,但是不幸的是它没有帮助. #1楼 我知道已经有 ...
- 让你分分钟理解 JavaScript 闭包
原文:https://www.cnblogs.com/onepixel/p/5062456.html 让你分分钟理解 JavaScript 闭包 闭包,是 Javascript 比较重要的一个概念,对 ...
- 全面理解Javascript闭包和闭包的几种写法及用途--转载自https://www.cnblogs.com/yunfeifei/p/4019504.html...
全面理解Javascript闭包和闭包的几种写法及用途 好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一 ...
- [转载]深入理解JavaScript闭包(closure)
最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...
最新文章
- python 使用安装虚拟环境 virtualenv
- 刻意练习:LeetCode实战 -- Task13. 罗马数字转整数
- 无线网络连接一直显示“正在获取网络地址”的解决办法
- 百度无线用户体验部2011年招聘计划
- 吴恩达《神经网络与深度学习》精炼笔记(5)-- 深层神经网络
- java ajax 获取headers_Ajax获取Response头信息
- 来自未来的缓存 Caffeine,带你揭开它的神秘面纱
- 查看创建的hive表对应的hdfs文件路径
- 页面上拖动图片进行排序
- python 反传播_反向传播算法详解和Python代码实现
- 165-手表品牌浅看一下
- linux中ll排序命令,ll命令
- html5技术之拉米牌游戏项目实战,国内首部HTML5技术之拉米牌游戏项目实战
- 【Unity】监听编辑器聚焦/激活状态OnEditorFocus
- (二十一)sift 特征点检测
- ElasticSearch 7.8.1教程(from b站狂神)+JD商城仿站
- 淘宝API应用调用官方买家信息数据
- java 邮箱地址生成器_关于java:生成随机电子邮件
- 【转】SAP物料主档关键栏位
- 无法登录到你的账户解决方案
热门文章
- java遍历两个日期_java 已知两个日期,遍历出两个日期之间所有的日期,重点是::包括第一个日期!!...
- linux+sed+-i替换路径,sed替换与别名配置
- pyspark读取hdfs 二进制文件
- PowerShell攻防进阶篇:nishang工具用法详解
- Mac VirtualBox 命令行Centos 调整窗口大小
- 20165219 预备作业3 Linux安装及学习
- java获取当前时间前一周、前一月、前一年的时间
- 【转载】Java Cache系列之Cache概述和Simple Cache
- 如何定义一个自己的可复用的JS文件
- 【转载】如何去除C#Strings中的空格?