0

I am looking into the Object.create to create a custom RegExp class. I want to use pure JS and not JQuery or other library. After spending time researching on MDN, here and other places, I find that my expectations and understand are still not quite adequate for my task.

So far I have this:

( function ( SEAC ) {
    var _NativeRegExp = RegExp,
        _NativeRegExpProto = _NativeRegExp.prototype;
    SEAC.RegExp = function ( ) { _NativeRegExp.apply( this, arguments ); };
    SEAC.RegExp.prototype = Object.create( _NativeRegExpProto );    
} )( self.SEAC || ( self.SEAC = {} ) );

If I use it in the following code:

var re = new SEAC.RegExp( "[aeiou]+", 'g' );
var match = 'The quickening'.match( re );

I get this response:

TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object]

I hope this the intention and question is clear enough.

Anyone can explain to me what I am doing wrong and/or suggest how to do this? Or maybe my approach is not the best way, suggest another. I have done this before without using Object.create, but I wish to see if this is a better way to deal with inheritance and class creation.

Why I want to do this is of course I want to customize the class and some of the native methods.

2
  • According to the specification, you cannot apply methods of RegExp.prototype to objects that are not instances of RegExp: "a TypeError exception is thrown if the this value is not an object or an object for which the value of the [[Class]] internal property is not "RegExp"." es5.github.io/#x15.10.6 . So I guess it's not possible to inherit from RegExp. Commented Dec 12, 2013 at 5:09
  • Hmmm.... that's to bad, I guess I will have to go back to an instance of a RegExp object inside of my custom RegExp and have each method applying that object method and then returning it, shame I have to wrap everything. Commented Dec 12, 2013 at 5:26

1 Answer 1

1

This seems a little derpy, but it seems that the browser is doing some type checking behind the scenes. This is my example that ran:

var Foo = function() {
  this.toString = function() {
    return "[object RegExp]";
  }
  return this;
};
Foo.prototype = Object.create(new RegExp);
var foo = new Foo("[aeiou]+", 'g' );
var match = 'The quickening'.match( foo );
console.log(match);
-- ["e", index: 2, input: "The quickening"] 

So its odd, but yeah just making sure that the toString is a function defined on the instance and it seems to work just fine... This is of course tricking the browsers internal "is a RegExp" check... so no guarantees on working for all cases... for example:

foo.exec("The quickening")

dies with:

TypeError: Method RegExp.prototype.exec called on incompatible receiver [object Object]

So perhaps a better approach would be to make your object just proxy through to an internal RegExp object that it makes when it is constructed... you can proxy all the RegExp methods you want and then also add your own. Its a little derpy but you could probably get more of the methods to work as expected. We do something similar with a Capped Array implementation: https://github.com/jive/JiveJS-Commons/blob/master/libs/capped.js But then again Array behaves a lot nicer than RegExp does for this kind of thing.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Nick. That is tremendously insane. I experimented with making an instance from native RegExp from the same arguments in the constructor and returning that in toString and that also doesn't work, it won't throw, but it basically makes the regexp empty. That basically means your suggestion can work but with the limitation that toString can not be used in any useful way. thanks for the reply!
Yeah, apparently RegExp plays crazy different from some of the other native Classes... its weird that it would, when you can do things with Array, Function and Object that you can't with RegExp... I played around with the making of a wrapper object that just in the constructor stores an internal reference to a RegExp instance and then just proxied the RegExp methods through... that seemed like the way to go. Still kinda derpy but functionaly clean

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.