Weird regex in inherit.js (by John Resig) - why, what and how? [duplicate]
Asked Answered
E

1

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?

Elisavetgrad answered 21/6, 2013 at 5:49 Comment(6)
Understanding John Resig's 'Simple JavaScript Inheritance'Workhorse
@Andreas: Wow, wish I found that earlier, just had to decipher this thing, but seems my findings are correct.Kieserite
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.Kieserite
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) :)Elisavetgrad
As I've only copied a link let @Kieserite write his answer one more time and reward him for his effort :)Workhorse
@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.Kieserite
K
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

Kieserite answered 21/6, 2013 at 6:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.