继承本地对象

4

我希望创建一个自己的RegExp子类,并添加额外的方法。以下是我采用的最简化的方法:

// Declare the subclass
function subRegExp(){}

// Inherit from the parent class
subRegExp.prototype = new RegExp();

// Create a new instance
regex = new subRegExp('[a-z]', 'g');

但我无法创建一个新实例。

这篇文章告诉我ECMAScript不支持原生对象的子类化,但已经过去了5年,所以我希望现在有一些选项。

我该如何实现这个呢?

编辑:这样可以吗?还是会遇到问题?

function subRegExp(str, flags){

    var instance = new RegExp(str, flags);

    // Custom method
    instance.setFlags = function(flags){
        return new subRegExp(this.source, flags);
    }

    return instance;
}

regex = new subRegExp('[a-z]', 'g');
4个回答

2

包装器是您的好朋友,也是提供扩展功能而无需使用继承的常见解决方案。

var MyRegexClass = function(regExpInstance) { 
  this.originalRegex = regExpInstance;
};

// Replicate some of the native RegExp methods in your wrapper if you need them.
MyRegexClass.prototype.test = function(str) {
    return this.originalRegex.test(str);
};

MyRegexClass.prototype.exec = function (str) {
    return this.originalRegex.exec(str);
};

// Now add in your own methods.
MyRegexClass.prototype.myCustomFunction0 = function () { 
    // this method does something with this.originalRegex
};
MyRegexClass.prototype.myCustomFunction1 = function () {
    // this method also does something with this.originalRegex
};

// Example usage
var matchDavids = new MyRegexClass(/David/);

// this call works, because my class provides the .test() method.
var hasMatch = matchDavids.test('David walked his dog to the park.');

// this call does not work, because my class does not expose the .compile() method.
matchDavids.compile();
// I would need to provide a .compile() method on MyRegexClass that calls to
// the originalRegex.compile().

是的,您会失去继承链。 MyRegexClass 不从原生的 RegExp 继承。根据我的经验,包装器比基于继承的扩展更易于测试和维护。


1
我尝试了这个:

// Declare the subclass
function subRegExp(){}
// make your object inherit from regex object
subRegExp.prototype = Object.create( RegExp.prototype );

var x = new subRegExp();
// see if your custom object inherited the RegExp properties/functions/methods
console.dir( "compile" in x );
console.dir( x.compile );

输出:

true
function compile() { [native code] }

是的,但是在新对象上调用本地构造函数可能不起作用。 - SuperJedi224

1

我很抱歉,它仍然不支持。

但是,您可以使用自定义包装对象类来模拟一些所需的功能。在构造函数中使用封装来将 RegExp 对象作为(Javascript 最接近的)私有字段。


我已经使用了您的想法编辑了我的问题,我有遗漏什么吗? - notyourtype
1
如果你那样做,就必须省略 new 关键字。 - SuperJedi224
1
@notyourtype,使用你的新代码实际上并没有创建一个子类。regex instanceof subRegExp 将会是 false。你只是创建了一个替代构造函数而已。(如果它返回的对象不是 this,那么你使用 new 调用它的事实基本上是无关紧要的。) - Jeremy

0
是的,在ES6中现在可以实现这个功能。
class R extends RegExp {}
var r = new R("baz", "g");
return r.exec("foobarbaz")[0] === "baz" && r.lastIndex === 9;

我们在ES6兼容性表中有一个测试,您可以看到哪些实现支持它

我会尽快更新我关于ES5中数组子类化的博客文章(您引用过的)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接