使用object.create自定义本机对象类,特别是Javascript中的RegExp

时间:2021-10-25 01:22:15

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.

我正在研究Object.create来创建一个自定义的RegExp类。我想使用纯JS而不是JQuery或其他库。花了很多时间研究MDN,在这里和其他地方,我发现我的期望和理解仍然不足以完成我的任务。

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]

TypeError:方法RegExp.prototype.toString在不兼容的接收器[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.

任何人都可以向我解释我做错了什么和/或建议如何做到这一点?或者也许我的方法不是最好的方法,建议另一种方法。我之前没有使用过Object.create,但是我希望看看这是否是处理继承和类创建的更好方法。

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

为什么我要这样做当然是我想自定义类和一些本机方法。

1 个解决方案

#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:

所以它奇怪,但是只是确保toString是一个在实例上定义的函数,它似乎工作得很好......这当然欺骗浏览器内部“是一个RegExp”检查...所以没有保证适用于所有情况......例如:

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.

所以也许更好的方法是让你的对象只是代理到它构造时所做的内部RegExp对象......你可以代理你想要的所有RegExp方法,然后再添加你自己的。它有点小,但你可能会得到更多的方法按预期工作。我们使用Capped Array实现做类似的事情:https://github.com/jive/JiveJS-Commons/blob/master/libs/capped.js但是然后Array再次表现得比RegExp对这种事情好很多。

#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:

所以它奇怪,但是只是确保toString是一个在实例上定义的函数,它似乎工作得很好......这当然欺骗浏览器内部“是一个RegExp”检查...所以没有保证适用于所有情况......例如:

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.

所以也许更好的方法是让你的对象只是代理到它构造时所做的内部RegExp对象......你可以代理你想要的所有RegExp方法,然后再添加你自己的。它有点小,但你可能会得到更多的方法按预期工作。我们使用Capped Array实现做类似的事情:https://github.com/jive/JiveJS-Commons/blob/master/libs/capped.js但是然后Array再次表现得比RegExp对这种事情好很多。