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

Javascript
我也种棵OO树JXTree[js+css+xml]
新浪中用来显示flash的函数
JXTree对象,读取外部xml文件数据,生成树的函数
用js来格式化字符串示例模仿css
js prototype 格式化数字 By shawl.qiu
新浪刚打开页面出来的全屏广告代码
记录几个javascript有关的小细节
Some tips of wmi scripting in jscript (1)
JavaScript Try...Catch 声明的 使用方法
JS版获取字符串真实长度和取固定长度的字符串函数
Javascript中的数学函数
ArrayList类(增强版)
javascript中巧用“闭包”实现程序的暂停执行功能
javascript判断单选框或复选框是否选中方法集锦
FireFox的getYear的注意事项
JavaScript For...In 使用方法
JavaScript Switch 声明
JavaScript If...Else 声明
JavaScript For 循环
JavaScript While 循环 教程

Javascript 中的 JS教程:匿名函数


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 465 ::
收藏到网摘: 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是对于每一个函数都可以使用,它提供给我们一个可靠的方法去访问函数自身。本人觉得,该方法比较简洁可靠。

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