2010-06-21 7 views
8

Je regardais le code du JIT, et je vis ceci:Javascript: Pourquoi utiliser une fonction anonyme ici?

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; 
      }; 

Quel pourrait être le but pour ces fonctions anonymes? Ils sont immédiatement hors de portée, n'est-ce pas?

Pourquoi utiliser:

 (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); 

au lieu de:

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

Est-ce une pirater JS super élite?

Répondre

12

Ils veulent juste mettre en œuvre récursion dans ce petit morceau de code:

(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); 

La propriété arguments.callee fait référence à la fonction en cours d'exécution, si vous supprimez la fonction anonyme, il fera référence à la fonction englobante et Je ne pense pas qu'ils veulent invoquer toute la fonction à nouveau.

+1

Intéressant. Je n'ai jamais vu 'arguments.callee' utilisé avant. –

+1

Vous pouvez également donner à l'expression de la fonction un identifiant. Dans ECMAScript 5, c'est la méthode préférée. – ChaosPandion

+2

@Chaos, Oui, est le moyen préféré, sous [mode strict] (http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) 'arguments.callee' est interdit sur ES5 ... mais utiliser des expressions de fonction nommées * now * peut causer des problèmes, car IE a un bogue sérieux et de longue date, où l'identificateur des expressions de fonction, manque à la portée englobante, en fait, deux objets de fonction sont créés ... Ce bug existe même sur IE9 Platform Preview ... Triste ... Voir aussi: [Les expressions de fonction nommées démystifiées] (http://yura.thinkweb2.com/named-function-expressions/) – CMS

Questions connexes