奇怪的JavaScript成语 - "/xyz/.test(function(){xyz;})"是做什么的?

Aki*_*idi 43 javascript regex function

John Resig写了一个漂亮的Class函数,时髦.我正在试图弄清楚发生了什么,除了一行之外,几乎所有事情都有所体现:

fnTest = /xyz/.test(function () {xyz;}) ? /\b_super\b/ : /.*/;
Run Code Online (Sandbox Code Playgroud)

一些事情立即浮现在脑海中,首先xyz永远不会被初始化为变量; 那么为什么这样呢?其次,为什么要/xyz/对没有返回任何东西的东西进行测试(没有返回语句).除非有javascript的一些漂亮的属性,我不知道(这是可能的,我觉得自己相当擅长JS并且可以解释大多数我遇到的代码不会,但是,这意味着我是在同一个山上的前夕.John Resig称之为珠穆朗玛峰大小的山.

对于那些好奇的人,这里是来自john resigs网站的完整未经编辑的代码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;
  };

})();
Run Code Online (Sandbox Code Playgroud)

CMS*_*CMS 51

检查"函数反编译"是否有效只是一种快速而又脏的方法.

RegExp.prototype.test方法将接受参数并将其转换为String,xyz函数内的引用永远不会被计算.

你为什么要检查这个?

因为该Function.prototype.toString方法返回函数的依赖实现的表示,并且在某些实现中,例如较旧的Safari版本,Mobile Opera和一些Blackberry浏览器,它们实际上并不返回任何有用的东西.

  • 只是添加一个注释:为了使测试通过jslint,它必须是/ var xyz/.test(function(){var xyz;})?/\b_super\b /:/ [\ D |\d]*/; 为什么\ D |\d简单,一个捕获所有数字,另一个捕获其他所有,它相当于.*但这被认为是'不安全',因为你没有定义限制.让我永远意识到他们的意思是不安全的'.'.投票给你,也标记为答案,非常感谢CMS. (4认同)
  • @trithithis,好吧,`typeof foo =='function`会起作用,但问题是你最终会包装每一个函数对象,即使它们不使用`_super`.Resig只是检查每个函数,看它是否在其体内使用`_super`标识符.如果`_super`出现在函数体上,那么他将那个函数包装到另一个函数中,在这个函数中,他首先通过赋值`this._super`来暴露"类"的"超级".然后他执行被检查的原始函数,并被证明使用`_super`,最后他恢复了`this._super`的值... (3认同)
  • @mykhal,`xyz`是你真正想要的,知道*函数反编译*正常工作.它只是检查转换为字符串的函数,生成一个包含函数体的字符串... (2认同)