您当时的方位:主页 > 言语编程 > JavaScript

JS匿名函数

2014-11-02  

毫无疑问,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是关于每一个函数都能够运用,它提供给咱们一个牢靠的办法去拜访函数本身。自己觉得,该办法比较简练牢靠。

综上所述,一切这些办法对咱们处理杂乱的代码结构将大有裨益。挑选运用能够使咱们的代码结构愈加简练明了,这也许是作者的初衷。