首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 网站建设 > ASP.NET > 诡异的JavaScript Closure
【标  题】:诡异的JavaScript Closure
【关键字】:JavaScript,Closure
【来  源】:http://blog.csdn.net/g9yuayon/archive/2007/04/18/1568980.aspx

诡异的JavaScript Closure

出来混,迟早要还。今天写JavaScript代码,才知道一个循环里的函数共享同一闭包。比如下面的代码是错的,不能正确报告每个事件对应的描述:

var div = document.getElementById("testDiv");
var events = {onclick: "clicked", onchange: "changed",  onmouseover: "mouse over"}; 

for(e in events){
   div[e] 
= function(){
      alert(events[e]);
   };
}

试一下就知道。不管激发events列表里的哪坨事件,alert弹出的窗口里总是"mouse over"。

不明白JavaScript为什么这样处理循环和闭包的关系。哪位老大指点一下?

阳春版的修改办法是利用函数定义创建新闭包,符合业内名言:任何计算机问题都能通过多加一层抽象解决。:-) Crockford Douglas 把多加的这层函数叫做因子函数(factor function)。

var div = document.getElementById("testDiv");
var events = {onclick: "clicked", onchange: "changed",  onmouseover: "mouse over"}; 

for(e in events){
   div[e] 
= function(e){
       
return function(){
           alert(events[e]);
       };
   }(e);
}

当然,如果到处创建因子函数,就繁琐了。所以还是Dojo风格的调用来得清爽:

dojo.lang.forEach(events, function(e){
    alert(e);
});

明眼老大们自然可以看出这是函数编程的风格。其实JavaScript本就是采用C语言句法的简化版LISP,异常灵活。如果我们注意利用高端函数(加上闭包),便可像搭建积木那样“拼装”我们的程序,使代码变得干净利落。Dojo框架里实现了各式函数编程常用函数,比如map, reduce, filter, find, hitch, curry, 非常方便。再加上prototype chain, 对inspection的强大支持(光arguments.caller, arguments.callee就让俺爱不释手了),以及call, apply, eval这三个超级函数,在JavaScript里写出功能完善的DSL也变得相对容易。 就算不捣腾DSL,JavaScript也有无数妙用。比如Dojo里处理事件的代码实现了AOP风格的建议功能,让我们随意操纵处理事件的时机,轻松截取任意事件的参数,哪怕是普通JavaScript函数调用的参数。而实现这些功能的代码并不复杂。

从Dojo的实现也可以看出学习多种编程范式的重要性。Dojo里支持函数编程,面向对象编程,Ruby风格的mixin, AOP风格的事件处理等从不同语言借鉴来的功能。如果Dojo的主程Alex Russell只懂JavaScript,就算他能倒背EMCAScript规范,恐怕也写不出Dojo。要享受编程,避免一件本来很美好的事变成体力活,功夫永远在诗外。

[UMU WSH 教程](13)常见对象 - Shell.Application:【上一篇】
lighttpd配置代理服务器:【下一篇】
【相关文章】
  • Pro JavaScript Techniques 学习笔记1
  • 利用javascript实现md5的本地加密
  • javascript哪位高手帮我解决这个程序的光标定位问题???
  • 集装箱箱号校验规则 javascript
  • javascript prototype介绍的文章
  • JAVASCRIPT捕捉用户按键,实现功能键
  • 如何使用javascript在html中获取url参数——很好用
  • Javascript中判断对象的基本类型
  • javascript原型模式实现OOP的再研究
  • Javascript RIA框架开发要点
  • 【随机文章】
  • java实现线程安全的三大利器
  • Linux循序渐进(4)
  • Linux 指令篇:使用者资讯与管理--chfn
  • dsniff的使用(原创)
  • 用Asp.Net使服务器重启
  • 第一次装ubuntu
  • 建立檢查使用者Quota的網頁
  • OCP DBA1学习笔记(2-5章)
  • CLFS-1.0.0rc4学习
  • Inetl JPEG Libarary编码BMP后图片翻转??
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.