2010-10-12 20 views
39

John Resig ha scritto una funzione di classe elegante, sciccoso. Sto cercando di capire cosa sta succedendo, e hanno praticamente tutto capito, tranne una sola riga:Strano linguaggio JavaScript - cosa fa "/xyz/.test(function(){xyz;})" fare?

fnTest = /xyz/.test(function() {xyz;}) ? /\b_super\b/ : /.*/; 

Un paio di cose saltano subito in mente, prima xyz non viene mai inizializzato come variabile; allora perché funziona? Secondo, perché sta testando /xyz/ contro qualcosa che non restituisce nulla (nessuna dichiarazione di ritorno). A meno che non ci siano alcune proprietà di javascript di cui sono inconsapevole (il che è possibile, mi piace piuttosto bene con JS e posso interpretare la maggior parte del codice che ho trovato non significa, tuttavia, che sono sullo stesso Mt . Montagna di dimensioni mai raggiunte che John Resig chiama a casa).

Per chi fosse curioso, ecco il codice inedito completo da John resigs sito John Resig Simple Javascript Inheritance:

(function() { 
    var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; 

    // The base Class implementation (does nothing) 
    this.Class = function(){}; 

    // Create a new Class that inherits from this class 
    Class.extend = function(prop) { 
    var _super = this.prototype; 

    // Instantiate a base class (but only create the instance, 
    // don't run the init constructor) 
    initializing = true; 
    var prototype = new this(); 
    initializing = false; 

    // Copy the properties over onto the new prototype 
    for (var name in prop) { 
     // Check if we're overwriting an existing function 
     prototype[name] = typeof prop[name] == "function" && 
     typeof _super[name] == "function" && fnTest.test(prop[name]) ? 
     (function(name, fn){ 
      return function() { 
      var tmp = this._super; 

      // Add a new ._super() method that is the same method 
      // but on the super-class 
      this._super = _super[name]; 

      // The method only need to be bound temporarily, so we 
      // remove it when we're done executing 
      var ret = fn.apply(this, arguments);  
      this._super = tmp; 

      return ret; 
      }; 
     })(name, prop[name]) : 
     prop[name]; 
    } 

    // The dummy class constructor 
    function Class() { 
     // All construction is actually done in the init method 
     if (!initializing && this.init) 
     this.init.apply(this, arguments); 
    } 

    // Populate our constructed prototype object 
    Class.prototype = prototype; 

    // Enforce the constructor to be what we expect 
    Class.constructor = Class; 

    // And make this class extendable 
    Class.extend = arguments.callee; 

    return Class; 
    }; 

})(); 
+1

.. controllo di integrità del lettore (in)? :) – mykhal

+0

.. hmm ho circondato il codice nei tag ..., mi chiedo perché ha fatto così male (nota > .. < non valuto per quello che penso dovrebbero oy, oggi non è il mio giorno – Akidi

risposta

49

E 'solo un rapido & modo sporco per verificare se "la funzione decompilazione" funziona.

Il metodo RegExp.prototype.test prenderà l'argomento e lo convertirà in String, il riferimento xyz all'interno della funzione non viene mai valutato.

Perché dovresti controllare questo?

Poiché il metodo restituisce un Function.prototype.toString rappresentazione dipende dall'implementazione di una funzione, e in qualche realizzazione, tali versioni precedenti di Safari, Mobile Opera, e alcuni browser Blackberry, in realtà non restituisce nulla di utile.

+0

quindi, non è il mio giorno il corpo della funzione anonima 'xyz' non è necessario? – mykhal

+1

@mykhal,' xyz' è ciò che stai effettivamente cercando, per sapere che * la decompilazione della funzione * funziona correttamente. Si tratta solo di verificare che una funzione convertita in stringa produca una stringa che contiene il corpo della funzione ... – CMS

+0

@CMS sì, ho finalmente capito dopo un po '..) – mykhal