2015-07-12 69 views
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'); 

但我無法創建一個新的實例。

This告訴我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'); 

回答

1

恐怕還是不行。

但是,您可以通過使用自定義包裝對象類來模擬一些必需的功能。在構造函數中使用封裝來爲其提供一個RegExp對象(Javascript最接近的)私有字段。

+0

我用你的想法編輯了我的問題,我錯過了什麼嗎? – notyourtype

+1

如果你這樣做,你必須省略'new'關鍵字。 – SuperJedi224

+1

@notyourtype使用你的新代碼,你實際上並沒有創建一個子類。 'regex instanceof subRegExp'將是'false'。你只是創建一個替代構造函數。 (事實上​​,你用'new'調用它實際上是不相關的,如果它返回一個Object而不是'this'。) –

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繼承。根據我的經驗,包裝比基於繼承的擴展更容易測試和維護。

+0

這看起來像一個很好的選擇 – notyourtype

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] } 
+0

是的,但是調用新對象的本地構造函數可能不會工作。 – SuperJedi224

0

是的,現在可以在ES6:

class R extends RegExp {} 
var r = new R("baz", "g"); 
return r.exec("foobarbaz")[0] === "baz" && r.lastIndex === 9; 

我們在ES6 COMPAT表它的測試在那裏你可以看到which implementations support it

我會盡快更新我的博客文章(您提到的)Array subclassing in ES5