7

I recently used a little utility library by John Resig, called inherit.js. I usually try to understand the core parts of the libraries I am using, and after a lot of head scratching I finally understood the hard bits of the code (namely how he could call the corresponding method of the super class).

The 1% bit I do not get is related to a regex

fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
  1. The regex /xyz/ is tested against a function. Both MSDN and MDN state that test takes a string as the argument. No mention of a function, but since there are no errors in the console, I guess it must fly, but how does it work?
  2. The next WTF is that the function body is xyz;. This function cannot be executed, because it would otherwise result in a "ReferenceError: xyz is not defined". Right? So what does it do?
  3. If the result of the test is true, then fnTest is equal to a regex which checks for _super on a word boundary, else a regex that matches on anything. Double WTF; again how and why.

Later on there is a related bit of code, where this regex is being used.

  // Check if we're overwriting an existing function
  prototype[name] = typeof prop[name] == "function" &&
    typeof _super[name] == "function" && fnTest.test(prop[name])
        ? aFunctionThatCanCallSuper /* Lots of code */
        : prop[name];

The bit I am wondering about here is fnTest.test(prop[name]). I understand all the other tests, which check if the property exists, is a function, etc, but not what the regex test does. Anyone?

oligofren
  • 20,744
  • 16
  • 93
  • 180
  • 1
    [Understanding John Resig's 'Simple JavaScript Inheritance'](http://blog.buymeasoda.com/understanding-john-resigs-simple-javascript-i/) – Andreas Jun 21 '13 at 06:14
  • @Andreas: Wow, wish I found that earlier, just had to decipher this thing, but seems my findings are correct. – elclanrs Jun 21 '13 at 06:16
  • Not even worth posting my answer, that link seems like the perfect answer. I'm guessing if you were to redo this library _today_ that check isn't necessary given that modern browsers will serialize correctly. – elclanrs Jun 21 '13 at 06:18
  • Great link! But for free points, you could post a quick sum up of the relevant points (or I will in a couple of days) :) – oligofren Jun 21 '13 at 06:31
  • As I've only copied a link let @elclanrs write his answer one more time and reward him for his effort :) – Andreas Jun 21 '13 at 06:42
  • @Andreas: When I deleted the answer I got rid of the edits, effectively loosing the answer but I'll sum it up so OP can close this question. – elclanrs Jun 21 '13 at 06:54

1 Answers1

6

The what:

test only takes strings as input, so a function will be toStringed, like will any other object that's not a string. xyz is not interpreted as a variable, but as a string, so it won't throw a reference error. This happens in other places as well, take this for example:

var a = function(){}; var b = function(){};
console.log(a + b); // `+` coerces with `toString`

The why:

The serialization of functions in old browsers is not reliable and might not output the _super property in the function's body, but (I'm assuming) something like function{[native code]} or [object Object]; in those cases use a regex such as /.*/ to match anything and not perform the optimizations that can be done in browsers that output the correct result.

Related links for more info:

http://blog.buymeasoda.com/understanding-john-resigs-simple-javascript-i/ (found by Andreas)
http://es5.github.io/x15.3.html#x15.3.4.2
http://bytes.com/topic/javascript/answers/747203-function-tostring

elclanrs
  • 92,861
  • 21
  • 134
  • 171