2010-06-21 11 views
8

stavo navigando codice del JIT, e ho visto questo:Javascript: Perché usare una funzione anonima qui?

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

Quale potrebbe essere lo scopo per quelle funzioni anonime? Passano immediatamente fuori dal campo di applicazione, giusto?

Perché usare:

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

invece di:

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

È questo alcuni JS Super Elite dell'hacking?

risposta

12

vogliono solo implementare la ricorsione in quel piccolo pezzo di codice:

(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 proprietà arguments.callee si riferisce alla funzione in corso di esecuzione, se si rimuove la funzione anonima, si farà riferimento alla funzione di inclusione, e Non penso che vogliano invocare di nuovo l'intera funzione.

+1

Interessante. Non ho mai visto 'arguments.callee 'usato prima. –

+1

Si potrebbe anche dare all'espressione della funzione un identificatore. In ECMAScript 5 questo è il metodo preferito. – ChaosPandion

+2

@Chaos, Sì, è il modo preferito, in [modalità rigorosa] (http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/) 'arguments.callee' non è consentito su ES5 ... ma l'utilizzo di espressioni di funzione denominate * now * può causare problemi, perché IE ha un bug grave, di vecchia data, in cui l'identificatore delle espressioni di funzione, manca per l'ambito che racchiude, in realtà, vengono creati due oggetti funzione ... Questo bug esiste anche su IE9 Platform Preview ... Triste ... Vedi anche: [Espressioni di funzioni con nome demistificate] (http://yura.thinkweb2.com/named-function-expressions/) – CMS

Problemi correlati