Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top