2010-10-12 11 views
39

John Resig escribió una ingeniosa función Class, elegante. Estoy tratando de averiguar lo que está pasando, y he casi todo lo descubierto, excepto una sola línea:Idioma idiomático extraño: ¿qué hace "/xyz/.test(function(){xyz;})"?

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

Un par de cosas saltan inmediatamente a la mente, primero xyz Nunca se inicializa como una variable; Entonces, ¿por qué funciona esto? En segundo lugar, ¿por qué está probando /xyz/ contra algo que no devuelve nada (sin declaración de devolución). A menos que haya algunas ingeniosas propiedades de javascript que desconozco (que es posible, me imagino que soy bastante bueno en JS y puedo interpretar la mayoría del código que encuentro, no significa, sin embargo, que estoy en el mismo Mt La montaña del Everest que John Resig llama hogar).

Para los curiosos, aquí está el código completo sin editar de John resigs sitio 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

.. lector (in) sanity check? :) – mykhal

+0

.. hmm rodeé el código en las etiquetas ..., me pregunto por qué lo mataron tan mal (nota > .. < no evalúo a lo que creo que deberían oy, hoy no es mi día. – Akidi

Respuesta

49

Es sólo una manera sucia & rápida para comprobar si "función de descompilación" funciona.

El método RegExp.prototype.test tomará el argumento y lo convertirá en cadena, la referencia xyz dentro de la función nunca se evalúa.

¿Por qué debería comprobar esto?

Debido a que el método devuelve un Function.prototype.toStringdependiente de la implementación representación de una función, y de alguna aplicación, tales versiones anteriores de Safari, Opera Mobile, y algunos navegadores de Blackberry, que en realidad no devuelve nada útil.

+0

entonces, no es el cuerpo de la función anónima 'xyz' es innecesario? – mykhal

+1

@mykhal,' xyz' es lo que realmente está buscando, saber que * la descompilación de funciones * funciona correctamente. Solo está comprobando que una función convertida a cadena, produce una cadena que contiene el cuerpo de la función ... – CMS

+0

@CMS sí, finalmente lo conseguí después de un tiempo ...) – mykhal