• ----:)欢迎访问源码网(:----
    • 首页
    • 博客
    • 学院
    • 下载
    • 论坛
    • 影视
    • 发布源码
    • RSS
    • ITPig
    • 笑话网
    • 百家姓
    • 繁體中文

源码网 - 中国第一源码门户
选择镜像:网通镜像 - 电信主站
  • 首 页
  • 新闻动态
  • 网站运营
  • 网页制作
  • WEB开发
  • 编程开发
  • 图像媒体
  • 操作系统
  • 数据库
  • 服务器
热门搜索 优化 SEO 故事 cms IIS7 MySQL 个人 AdSense 主题推广 | 文章搜索: 高级搜索
会员登录/控制面版您的位置: 学院首页 >> 网页制作 >> Javascript >> 详细内容
 

推荐文章

 
 

热点文章

  • 北京2008年奥运会金牌排行榜 调用163
  • JavaScript实现图片幻灯片效果的源代码
  • 腾讯迷你天气预报代码
  • javascript汉字转拼音 功能块,方法很笨但很实用
  • JavaScript中常用正则表达式
  • JavaScript使用Window对象
  • javascript 实现无刷新联动菜单select的方法
  • 网页设计配色应用实例剖析——绿色系
  • 自然界的色彩搭配与界面设计(1)
  • javascript脚本轻松实现局部刷新
  • JavaScript自定义模式对话框
  • 浮动菜单是如何作出来的mouse事件
 
 

相关文章

  • Webkit 最新 Javascript 引擎领先 Chrome
  • JavaScript对SEO的影响及解决之道
  • Javascript实现打印网页中的定义的部分内容
  • Javascript 遮罩层 兼容性好。支持IE,firefox 页面变灰..
  • javascript中createTextRange用法
  • javascript的createTextRange方法
  • javascript中的moveStart和moveEnd方法
  • JavaScript中For循环
  • javascript常用脚本代码
  • 几种javascript的改进写法
  • JavaScript的函数式编程的对象本质
  • javascript判断文件存在
 
 

百度搜索

 
 

在Javascript中,什么是闭包(Closure)

  • 阅览次数:
  • 文章来源: CodePub整理
  • 原文作者:
  • 整理日期: 2008-09-21
  • 发表评论
  • 字体大小:
  • 小
  • 中
  • 大

闭包的两个特点:

1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

例1。
复制内容到剪贴板
代码:
<script type="text/javascript">
function sayHello2(name) {
var text = 'Hello ' + name; // local variable
var sayAlert = function() { alert(text); }
return sayAlert;
}
var sy = sayHello2('never-online');
sy();
</script>
作为一个Javascript程序员,应该明白上面的代码就是一个函数的引用。如果你还不明白或者不清楚的话,请先了解一些基本的知识,我这里不再叙述。

上面的代码为什么是一个闭包?
因为sayHello2函数里有一个内嵌匿名函数
sayAlert = function(){ alert(text); }
在Javascript里。如果你创建了一个内嵌函数(如上例),也就是创建了一个闭包。

在C或者其它的主流语言中,当一个函数返回后,所有的局部变量将不可访问,因为它们所在的栈已经被消毁。但在Javascript里,如果你声明了一个内嵌函数,局部变量将在函数返回后依然可访问。比如上例中的变量sy,就是引用内嵌函数中的匿名函数function(){ alert(text); },可以把上例改成这样:
复制内容到剪贴板
代码:
<script type="text/javascript">
function sayHello2(name) {
var text = 'Hello ' + name; // local variable
var sayAlert = function() { alert(text); }
return sayAlert;
}
var sy = sayHello2('never-online');
alert(sy.toString());
</script>
这里也就与闭包的第二个特点相吻合。

例2。
<script type="text/javascript">
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}

var sy = say667();
sy();
alert(sy.toString());
</script>

上面的代码中,匿名变量function() { alert(num); }中的num,并不是被拷贝,而是继续引用外函数定义的局部变量——num中的值,直到外函数say667()返回。

例3。
复制内容到剪贴板
代码:
<script type="text/javascript">
function setupSomeGlobals() {
// Local variable that ends up within closure
var num = 666;
// Store some references to functions as global variables
gAlertNumber = function() { alert(num); }
gIncreaseNumber = function() { num++; }
gSetNumber = function(x) { num = x; }
}

</script>
<button onclick="setupSomeGlobals()">生成 - setupSomeGlobals()</button>
<button onclick="gAlertNumber()">输出值 - gAlertNumber()</button>
<button onclick="gIncreaseNumber()">增加 - gIncreaseNumber()</button>
<button onclick="gSetNumber(5)">赋值5 - gSetNumber(5)</button>
上例中,gAlertNumber, gIncreaseNumber, gSetNumber都是同一个闭包的引用,setupSomeGlobals(),因为他们声明都是通过同一个全局调用——setupSomeGlobals()。
你可以通过“生成”,“增加”,“赋值”,“输出值”这三个按扭来查看输出结果。如果你点击“生成”按钮,将创建一个新闭包。也就会重写gAlertNumber(), gIncreaseNumber(), gSetNumber(5)这三个函数。

如果理解以上代码后,看下面的例子:

例4。
复制内容到剪贴板
代码:
<script type="text/javascript">
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}

function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}

testList();
</script>
运行结果:
item 3 is undefined
item 3 is undefined
item 3 is undefined

代码result.push( function() {alert(item + ' ' + list[i])} ),
使result数组添加了三个匿名函数的引用。这句代码也可以写成
var p = function() {alert(item + ' ' + list[i])};
result.push(p);
关于为什么会输出三次都是 "item 3 is undefined"

在上面的例子say667()例子中已经解释过了。
匿名函数
复制内容到剪贴板
代码:
function() {alert(item + ' ' + list[i])}[code]中的[code]list[i]
并不是经过拷贝,而是对参数list的一个引用。直到函数buildList()返回为止,也就是说,返回最后一个引用。即遍历完list(注:list的最大下标应该是2)后,经过i++也就变成了3,这也就是为什么是item 3,而list[3]本身是没有初始化的,自然也就是undefined了。

例5。
复制内容到剪贴板
代码:
<script type="text/javascript">
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
alert('num: ' + num +  
'nanArray ' + anArray.toString() +  
'nref.someVar ' + ref.someVar);
}
}
var closure1 = newClosure(40, {someVar:' never-online'})
var closure2 = newClosure(99, {someVar:' BlueDestiny'})
closure1(4)
closure2(3)
</script>
在这最后一个例子中,展示如何声明两个不同的闭包。

上一篇:js遍历操作某一区域的图片元素
下一篇:少走弯路Web开发网站制作十八条心得
  • 网友评论:
  • 查看所有评论
  • 我要发表评论
您的网名:
留言主题:
你要发表的内容:

 

关于本站 | 广告联系 | 版权声明 | 网站地图 | 发布软件 | 帮助中心 | 源码论坛

Copyright © 2005-2007 CodePub.Com  程序支持:木翼  滇ICP备05005971号