当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JS教程:匿名函数

Javascript
关于javascript document.createDocumentFragment()
javascript 有趣而诡异的数组
javascript 兼容鼠标滚轮事件
javascript mouseover、mouseout停止事件冒泡的解决方案
javascript 放大镜效果js组件 qsoft.PopBigImage.v0.35 加入了chrome支持
javascript 表格排序和表头浮动效果(扩展SortTable)
Cookie 注入是怎样产生的
javascript RadioButtonList获取选中值
javascript fullscreen全屏实现代码
常用简易JavaScript函数
用js实现的检测浏览器和系统的函数
File文件控件,选中文件(图片,flash,视频)即立即预览显示
js 获取键盘值用法(兼容IE及Firefox)
javascript 鼠标滚轮事件
javascript 原型模式实现OOP的再研究
js 判断浏览器类型 去全角、半角空格 自动关闭当前窗口
javascript html 静态页面传参数
Firefox window.close()的使用注意事项
javascript removeChild 使用注意事项
js cookies 常见网页木马挂马代码 24小时只加载一次

Javascript 中的 JS教程:匿名函数


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 372 ::
收藏到网摘: n/a

毫无疑问,John Resig 是一个细致且善于思考的人,对于我们通常使用的匿名函数,在他的细究之下,也能挖掘出一些新的东西。通常情况下,当一个函数调用自身时,递归就出现了,对于下面这样的函数调用,我们并不陌生。

1.function yell(n){
2.       return n > 0 ? yell(n-1) + "a" : "hiy";
3.}
4.alert( yell(4))//结果为:hiyaaaa;

单个函数看不出任何问题,如果我们使用匿名函数,并将其放置到一个对象内部,结果会怎样?

1.var ninja = {
2.         yell: function(n){
3.                 return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
4.         }
5.};
6.alert( yell(4))//结果为:hiyaaaa;

现在我们看不出任何问题所在,如果我们创建一个新的对象,从ninja 那里复制yell方法,情况就有所不同了。既然匿名函数在ninja 内部,那么该方法仍是对ninja对象yell方法的引用。如果我们重新定义ninja对象,问题就出现了。


01.var ninja = {
02.           yell: function(n){
03.                 return n > 0 ? ninja.yell(n-1) + "a" : "hiy";
04.          }
05.};
06.var samurai = { yell: ninja.yell };
07.var ninja = {};
08.try {
09.       alert(samurai.yell(4);
10.} catch(e){
11.       alert("Uh, this isn't good! Where'd ninja.yell go?" );
12.}
13.//结果是:"Uh, this isn't good! Where'd ninja.yell go?"

如何解决该问题?如何使yell方法更可靠?最常见的方法是在ninja.yell方法内部使用“this”来改变ninja对象的所有实例,即:

1.var ninja = {
2.          yell: function(n){
3.                return n > 0 ? this.yell(n-1) + "a" : "hiy";
4.         }
5.};

现在我们测试,将会得到我们需要的结果。这当然是一种方法,另外一种方法是给匿名函数命名,这看似矛盾,但的确能很好的工作,瞧:


01.var ninja = {
02.           yell: function yell(n){
03.                  return n > 0 ? yell(n-1) + "a" : "hiy";
04.           }
05.};
06.alert((ninja.yell(4)) + "  Works as we would expect it to!" );
07.var samurai = { yell: ninja.yell };
08.var ninja = {};
09.alert( (samurai.yell(4))+ "  The method correctly calls itself." );

给匿名函数命名可以更进一层,对于正常的变量声明,我们也可以尝试这样做,如:


1.var ninja = function myNinja(){
2.        alert( (ninja == myNinja) + " This function is named two things - at once!" );
3.};
4.ninja();

运行上面的这个函数,在 IE中,我么看到的是:”flase This function is named two things – at once!”,在FF中我们看到的是:”true This function is named two things – at once!”。作者曾指出:匿名函数可以命名,但只在函数自身内部可见。看来并不是那么回事,测试结果表明,对于IE,并不可见,而在FF中,结果正如作者所料。同时,我们检测myNinja,结果在IE和FF也有所不同。


1.alert( typeof myNinja);
2.//在FF中为"undefinde"
3.//在IE中为"function"

这样看来,给匿名函数命名,在IE中,只在外部可见;在FF中,只在函数内部可见。其实,我们可以使用arguments.callee获得我们所需要的结果,如下:


1.var ninja = {
2.            yell: function(n){
3.                   return n > 0 ? arguments.callee(n-1) + "a" : "hiy";
4.            }
5.};
6.alert( ninja.yell(4));

Arguments.callee是对于每一个函数都可以使用,它提供给我们一个可靠的方法去访问函数自身。本人觉得,该方法比较简洁可靠。

综上所述,所有这些方法对我们处理复杂的代码结构将大有裨益。选择使用可以使我们的代码结构更加简洁明了,这也许是作者的初衷。