2010-06-21 95 views
8

我瀏覽了JIT的代碼,我看到了這一點:Javascript:爲什麼在這裏使用匿名函數?

var isGraph = ($type(json) == 'array'); 
    var ans = new Graph(this.graphOptions); 
    if(!isGraph) 
     //make tree 
     (function (ans, json) { 
      ans.addNode(json); 
      for(var i=0, ch = json.children; i<ch.length; i++) { 
       ans.addAdjacence(json, ch[i]); 
       arguments.callee(ans, ch[i]); 
      } 
     })(ans, json); 
    else 
     //make graph 
     (function (ans, json) { 
      var getNode = function(id) { 
       for(var w=0; w<json.length; w++) { 
        if(json[w].id == id) { 
        return json[w]; 
        } 
       } 
       return undefined; 
      }; 

有什麼能爲那些匿名函數的目的是什麼?他們立即超出範圍,對吧?

爲什麼要使用:的

 (function (ans, json) { 
      ans.addNode(json); 
      for(var i=0, ch = json.children; i<ch.length; i++) { 
       ans.addAdjacence(json, ch[i]); 
       arguments.callee(ans, ch[i]); 
      } 
     })(ans, json); 

代替:

  ans.addNode(json); 
      for(var i=0, ch = json.children; i<ch.length; i++) { 
       ans.addAdjacence(json, ch[i]); 
       arguments.callee(ans, ch[i]); 
      } 

這是一些超級精英JS砍?

回答

12

他們只是想實現的是一小段代碼,遞歸:

(function (ans, json) { 
     ans.addNode(json); 
     for(var i=0, ch = json.children; i<ch.length; i++) { 
      ans.addAdjacence(json, ch[i]); 
      arguments.callee(ans, ch[i]); // <-- recursion! 
     } 
    })(ans, json); 

arguments.callee屬性是指當前正在執行的功能,如果你刪除匿名函數,它將是指封閉功能,我不認爲他們想要再次調用整個函數。

+1

有趣。我以前從未見過'arguments.callee'。 – 2010-06-21 04:43:11

+1

您也可以給函數表達式一個標識符。在ECMAScript 5中,這是首選的方法。 – ChaosPandion 2010-06-21 04:47:20

+2

@Chaos,是的,是[嚴格模式]下的首選方式(http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/)'arguments.callee'是不允許的ES5 ...但使用命名函數表達式* now *可能會導致問題,因爲IE有一個嚴重的,長期存在的錯誤,其中函數表達式的標識符缺少封閉範圍,實際上創建了兩個函數對象...這個bug甚至存在於IE9平臺預覽中...悲傷......另請參見:[命名函數表達式揭祕](http://yura.thinkweb2.com/named-function-expressions/) – CMS 2010-06-21 04:52:19

相關問題