【问题标题】:using object.create to customize a native object class, specifically RegExp in Javascript使用 object.create 自定义原生对象类,特别是 Javascript 中的 RegExp
【发布时间】:2013-12-12 13:23:22
【问题描述】:

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

到目前为止,我有这个:

( 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 = {} ) );

如果我在下面的代码中使用它:

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

我收到以下回复:

TypeError:方法 RegExp.prototype.toString 调用不兼容 接收者[对象对象]

我希望这个意图和问题足够清楚。

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

为什么要这么做,当然是想自定义类和一些原生方法。

【问题讨论】:

  • 根据规范,您不能将RegExp.prototype 的方法应用于不是RegExp 实例的对象:"如果this 值不是对象或 [[Class]] 内部属性的值不是 "RegExp" 的对象。" es5.github.io/#x15.10.6 。所以我想不可能从RegExp继承。
  • Hmmm.... 太糟糕了,我想我将不得不回到我的自定义 RegExp 中的 RegExp 对象的实例,并让每个方法应用该对象方法然后返回它,可惜我必须把所有东西都包起来。

标签: javascript regex prototype prototypal-inheritance


【解决方案1】:

这似乎有点古怪,但似乎浏览器正在幕后进行一些类型检查。这是我运行的示例:

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"] 

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

foo.exec("The quickening")

死于:

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

因此,也许更好的方法是让您的对象仅代理到它在构造时生成的内部 RegExp 对象……您可以代理所有您想要的 RegExp 方法,然后添加您自己的方法。它有点愚蠢,但您可能可以获得更多按预期工作的方法。我们对 Capped Array 实现做了类似的事情:https://github.com/jive/JiveJS-Commons/blob/master/libs/capped.js 但话说回来,Array 在这种事情上的表现比 RegExp 好得多。

【讨论】:

  • 谢谢尼克。这太疯狂了。我尝试从构造函数中的相同参数从本机 RegExp 创建一个实例,然后在 toString 中返回它,这也不起作用,它不会抛出,但它基本上使 regexp 为空。这基本上意味着您的建议可以工作,但限制 toString 不能以任何有用的方式使用。感谢您的回复!
  • 是的,RegExp 显然与其他一些本地类不同......这很奇怪,当你可以用数组、函数和对象做你不能用 RegExp 做的事情时。 ..我尝试制作一个包装对象,该对象仅在构造函数中存储对 RegExp 实例的内部引用,然后只是通过代理 RegExp 方法……这似乎是要走的路。仍然有点呆板,但功能上很干净
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-05
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 2023-04-08
相关资源
最近更新 更多