`
jinhailion
  • 浏览: 45959 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

javascript 循环中使用匿名函数

 
阅读更多
一、什么是匿名函数?
在Javascript定义一个函数一般有如下三种方式:

函数关键字(function)语句:
function fnMethodName(x){alert(x);}

函数字面量(Function Literals):
var fnMethodName = function(x){alert(x);}

Function()构造函数:
var fnMethodName = new Function('x','alert(x);')


上面三种方法定义了同一个方法函数fnMethodName,第1种就是最常用的方法,后两种都是把一个函数复制给变量fnMethodName,而这个函数是没有名字的,即匿名函数。实际上,相当多的语言都有匿名函数。

二、函数字面量和Function()构造函数的区别
虽然函数字面量是一个匿名函数,但语法允许为其指定任意一个函数名,当写递归函数时可以调用它自己,使用Function()构造函数则不行。
var f = function fact(x) {
  if (x < = 1) return 1;
  else return x*fact(x-1);
};

Function()构造函数允许运行时Javascript代码动态的创建和编译。在这个方式上它类似全局函数eval()。
Function()构造函数每次执行时都解析函数主体,并创建一个新的函数对象。所以当在一个循环或者频繁执行的函数中调用Function()构造函数的效率是非常低的。相反,函数字面量却不是每次遇到都重新编译的。
用Function()构造函数创建一个函数时并不遵循典型的作用域,它一直把它当作是顶级函数来执行。
var y = "global";
function constructFunction() {
    var y = "local";
    return new Function("return y");  //  无法获取局部变量
}
alert(constructFunction()());  // 输出 "global"

和函数关键字定义相比Function()构造器有自己的特点且要难以使用的多,所以这项技术通常很少使用。而函数字面量表达式和函数关键字定义非常接近。考虑前面的区别,虽然有消息说字面量的匿名函数在OS X 10.4.3下的某些webkit的引擎下有bug,但我们平常所说的匿名函数均指采用函数字面量形式的匿名函数。更多详细内容可以阅读《JavaScript: The Definitive Guide, 5th Edition》的Functions那章。

三、匿名函数的代码模式
昨天hedger wang在他的blog介绍了几种匿名函数的代码模式:

错误模式:其无法工作,浏览器会报语法错。
function(){
  alert(1);
}();

函数字面量:首先声明一个函数对象,然后执行它。
(function(){
  alert(1);
} ) ( );

优先表达式:由于Javascript执行表达式是从圆括号里面到外面,所以可以用圆括号强制执行声明的函数。
( function(){
  alert(2);
} ( ) );

Void操作符:用void操作符去执行一个没有用圆括号包围的一个单独操作数。
void function(){
  alert(3);
}()

这三种方式是等同的,hedger wang因为个人原因比较喜欢第3种,而在实际应用中我看到的和使用的都是第1种。

四、匿名函数的应用
《Javascript的一种模块模式》中的第一句话就是“全局变量是魔鬼”。配合var关键字,匿名函数可以有效的保证在页面上写入Javascript,而不会造成全局变量的污染。这在给一个不是很熟悉的页面增加Javascript时非常有效,也很优美。实际上,YUI以及其相应的范例中大量使用匿名函数,其他的Javascript库中也不乏大量使用。
Javascript的函数式编程(functional programming)的基石.具体请看《用函数式编程技术编写优美的 JavaScript》和《函数式JavaScript编程指南》。

----------------------------------------------------------------------------------

先看下面的代码
<SCRIPTLANGUAGESCRIPTLANGUAGE="JavaScript"> 
 functionDelete_Row(i)  
 {  
alert(i);  
 }  
 functiontest()  
 {  
 for(vari=0;i<5;i++)  
 {  
vartable11=document.getElementById("table11");  
vartr11=table11.insertRow();  
vartrstr="tr"+tr11.rowIndex;  
tr11.id=trstr;  
  
tr11.ondblclick=function()  
{  
 Delete_Row(trstr);  
};  
  
vartd11=tr11.insertCell();  
td11.innerHTML=i;  
td11=tr11.insertCell();  
td11.innerText="我爱你";  
td11=tr11.insertCell();  
td11.innerText="笨蛋";  
td11=tr11.insertCell();  
  
}  
}  
 //--> 
 </SCRIPT> 
 <tableidtableid="table11"border=1> 
 <tbody> 
 <tr> 
 <td>第一列</td> 
 <td>第二列</td> 
 <td>第三列</td> 
 </tr> 
 </tbody> 
 </table> 
 <br> 
 <inputtypeinputtype="button"value="GO"onclick="test()"> 


点击按钮之后,会在table11中插入5行,行的双击事件就是使用了JavaScript匿名函数。

试想,点击第2行和第3行,你会看到什么,会是alert('tr0')和alert('tr1')吗,和你想的一样?

很显然不是我想要的结果,而是弹出了alert('tr5'),真是有点儿怪哦!可以肯定的是问题肯定是出在JavaScript匿名函数上,有可能是这个行的双击事件都指向了同一下JavaScript匿名函数,不知道各位有什么看法?

而把上述代码修改成如下代码,就会得到我们想到的结果。

<SCRIPTLANGUAGESCRIPTLANGUAGE="JavaScript"> 
 functionDelete_Row(i)  
 {  
    alert(i);  
 }  

 functiontest()  
 {  
   for(vari=0;i<5;i++)  
   {  
   
      vartable11=document.getElementById("table11");  
  
      vartr11=table11.insertRow();  
      vartrstr="tr"+tr11.rowIndex;  
      tr11.id=trstr;  
  
      tr11.ondblclick=f(trstr);  
      vartd11=tr11.insertCell();  
      td11.innerHTML=i;  
      td11=tr11.insertCell();  
      td11.innerText="我爱你";  
      td11=tr11.insertCell();  
      td11.innerText="笨蛋";  
      td11=tr11.insertCell();  
    }  
  }  

  functionf(i)  
  {  
     return function()  
  {  
 Delete_Row(i);  
  }  
}  
 //--> 
 </SCRIPT> 
 <tableidtableid="table11"border=1> 
 <tbody> 
 <tr> 
 <td>第一列</td> 
 <td>第二列</td> 
 <td>第三列</td> 
 </tr> 
 </tbody> 
 </table> 
 <br> 
 <inputtypeinputtype="button"value="GO"onclick="test()"> 



http://www.jb51.net/article/21948.htm
剖析的很好,小括号不但只是优先级的作用。还有更重要的作用,它进行运算,如果里面是表达式则运算出结果,如果里面是匿名函数则返回函数对象。
分享到:
评论

相关推荐

    JavaScript详解(第2版)

     7.1.3 匿名函数变量   7.1.4 闭包   7.1.5 递归   7.1.6 函数是对象   7.2 调试技巧   7.2.1 函数语法   7.2.2 使用try/catch和throw捕捉异常   7.3 应知应会   练习   第8章 对象  ...

    JavaScript经典实例

     6.10使用匿名函数包装全局变量  第7章处理事件  7.0简介  7.1检测页面何时完成载入  7.2使用Event对象捕获鼠标点击事件的位置  7.3创建一个通用的、可重用的事件处理函数  7.4根据修改的条件来取消一个事件 ...

    源文件程序天下JAVASCRIPT实例自学手册

    3.3.1 匿名函数 3.3.2 显式声明 3.3.3 手工触发 3.4 事件处理器的返回值 3.5 事件处理器设置的灵活性 3.6 现代事件模型与Event对象 3.7 IE4中的Event对象 3.7.1 对象属性 3.7.2 事件上溯 3.7.3 阻止事件上溯 3.7.4 ...

    JavaScript实例精通

    6_4.htm 使用匿名函数为定时器传递参数。 6_5.htm Web页面中的tooltip提示。 6_6.htm 在Web页面中控制其元素的选择状态。 第7章(\7) 示例描述:JavaScript的鼠标事件和键盘事件。 7_1.htm 按钮的鼠标单击...

    《JavaScript实例精通》[源代码]

    6_4.htm 使用匿名函数为定时器传递参数。 6_5.htm Web页面中的tooltip提示。 6_6.htm 在Web页面中控制其元素的选择状态。 第7章(\7) 示例描述:JavaScript的鼠标事件和键盘事件。 7_1.htm 按钮的鼠标单击...

    JavaScript实战

    5.9.1 匿名函数 150 5.9.2 this和$(this) 150 5.10 自动提取引用 152 5.10.1 概览 152 5.10.2 编程 153 第6章 动作/响应:让页面通过事件活动起来 156 6.1 什么是事件 156 6.1.1 鼠标事件 158 6.1.2 文档/窗口事件 ...

    JavaScript基础和实例代码

    3.3.1 匿名函数 3.3.2 显式声明 3.3.3 手工触发 3.4 事件处理器的返回值 3.5 事件处理器设置的灵活性 3.6 现代事件模型与Event对象 3.7 IE4中的Event对象 3.7.1 对象属性 3.7.2 事件上溯 3.7.3 阻止事件上溯 3.7.4 ...

    javascript高级教程

     匿名函数,它常作为参数在其他函数间传递:  window.addEventListener('load',function(){  //执行的语句  },false);  5、对象  Javascript的一个重要功能就是基于对象的功能,通过基于对象的程序设计,可以...

    Node.js MongoDB AngularJSWeb开发中文版.part1

    2.5.4 使用匿名函数 21 2.6 理解变量作用域 22 2.7 使用JavaScript对象 22 2.7.1 使用对象语法 23 2.7.2 创建自定义对象 23 2.7.3 使用原型对象模式 24 2.8 处理字符串 25 2.8.1 合并字符串 26 2.8.2 在字符串中搜索...

    javascript入门笔记

    Javascript Basic 1、Javascript 概述(了解) Javascript,简称为 JS,是一款能够运行在 JS解释器/引擎 中的脚本语言 ... 1、定义一个函数 change ,该函数中接收两个参数(a,b) 2、在函数体中,如果 a 大于 b的话...

    JavaScript笔记

    构造函数中的参数都是字符串 结论:所有的方法都是function类型的。 15.JavaScript中的所有事物都是对象,分为三类: |--简单对象:String、Number、Boolean |--组合对象:Array、Math、Date |--复杂对象:...

    closer.js:JavaScript中的Clojure解析器和核心库,与Mozilla Parser API兼容

    Closer.js Closer.js是使用JavaScript编写的的,与兼容。 它还将大部分库作为一个(很大程度上要感谢 )。...匿名函数文字 clojure.core提供了100多个功能 许多核心功能可以使用惰性序列,例如range ,

    javascript 常见的闭包问题的解决办法

    但是当外层中出现循环的时候,如果在里层函数中利用这个循环变量的话,会直接引用这个变量的最终值。 就像上述代码演示的一样。 如何解决呢。 可以利用匿名函数来加以解决。匿名函数会制动执行,我们可以利用这一...

    JavaScript开发时的五个注意事项

    JavaScript开发时的五个注意事项讲述了表单事件、链接、循环优化、匿名函数、字符串连接等优化技巧,需要的朋友可以参考一下

    dead-simple:JavaScript中死掉的简单PubSub和EventEmitter

    因此,您可以使用匿名函数。 可读:代码中没有神奇的东西; 除了简单。 现代:使用新的但得到功能。 高效:没有内存泄漏,没有重复的调用,没有额外的循环。 干净的API: sub和pub (或on和emit ),不需要多了,不...

    JavaScript-Patterns:一组不同的 JS Patterns 供参考

    JavaScript 模式 一组不同的 JS Patterns 供参考 从网络上的各种来源和我自己的作品中收集 匿名函数 班级 条件句 循环 转变 对象字面量 jQuery 插件 信用: :

    那些精彩的JavaScript代码片段

    精彩的JavaScript代码片段,分享给大家 1.根据给定的条件在原有的数组上,得到所需要的新数组 var a = [-1, -1, 1, 2, -2, -2, -3, -3, 3, -3];... // 传输一个匿名函数作为逻辑判断 2.比原生type或typeof更详细的

    define:最小的AMD JavaScript模块加载器!

    通过解析函数中的require(...)调用来隐式依赖 配置或插件 如果需要,您可以考虑使用其他诸如requirejs(最小化15kB)之类的东西。 缩小define.js $ npm install $ npm run build 输出将是define.min.js 运行测试 ...

    babel-plugin-relooper

    只要Babel可以确定您是在实际的数组上调用它们,并且使用的是匿名函数表达式,则此插件会将对数组方法的调用转换回普通循环。 这样我可以继续踩住.map , .reduce和whathaveyou到处没有给出有关性能该死。 万岁! ...

    performance-javascript-patterns:这是关于模式,声明和执行的快速性能测试

    性能javascript模式这是关于模式,声明和执行的快速性能测试这些只是一些测试,但是我将在下个周末添加更多测试。在Chrome上运行版本:44.0.2403.157(64位) //循环外的局部声明; variable [i] ='variable'+ i +'...

Global site tag (gtag.js) - Google Analytics