43 votes

Étrange JavaScript langage - que signifie "/xyz/.test(function(){xyz;})" faire?

John Resig a écrit une chouette fonction de Classe, chic. Je suis à essayer de comprendre ce qui se passe, et ont à peu près tout compris sauf une seule ligne:

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

Un couple de choses de sauter immédiatement à l'esprit, première xyz n'est jamais initialisée comme une variable, alors pourquoi cela fonctionne? Deuxièmement, pourquoi est-il test /xyz/ contre quelque chose qui n'est pas de retourner quoi que ce soit (pas d'instruction return). Sauf s'il y a quelques chouettes propriétés de javascript, je suis pas d' (ce qui est possible, je crois moi-même plutôt bon en JS et peut interpréter plus le code que j'ai trouver il n'est pas, cependant, dire que je suis en veille sur le même Mt. L'Everest de la taille de la montagne que John Resig appelle à la maison).

Pour les curieux, voici l'intégrale inédite code de john resigs site de John Resig Javascript Simple Héritage:

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

})();

51voto

CMS Points 315406

C'est juste un moyen rapide et sale façon de vérifier si la fonction de "décompilation" fonctionne.

L' RegExp.prototype.test méthode va prendre l'argument et il va le convertir en Chaîne de caractères, l' xyz de référence à l'intérieur de la fonction n'est jamais évaluée.

Pourquoi devriez-vous vérifier?

Parce que l' Function.prototype.toString méthode retourne un dépendant de l'implémentation de la représentation d'une fonction, et dans certains de la mise en œuvre, telles les anciennes versions de Safari, Opera Mobile, et certains Blackberry navigateurs, ils n'ont pas réellement de retour quelque chose d'utile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X