Visto che secondo me è meglio reinventare la ruota (solo quando non è troppo grande ), me lo sono scritto da solo il polyfiller

(Solo che anziché String.match(RegExp) l'ho fatto RegExp.exec(String): è la stessa cosa, no?)

Che ne pensi?

codice:
var namedRegExp = function (expression, flags) {
    var __namedGroups = [],
        __isNamed = [],
        exp;
    
    expression = expression.replace(/\((\?(?:P?<([^>]+)>|'([^']+)'))?/g, function (name) {
        __isNamed.push(/^\(\?(?:P?<([^>]+)>|'([^']+)')$/.test(name));
        __namedGroups.push(name.replace(/^\(\?(?:P?<([^>]+)>|'([^']+)')$/, function (name, inAngularBrackets, inSingleQuotes) {
            return inAngularBrackets || inSingleQuotes;
        }));
        return "(";
    });


    exp = new RegExp(expression, flags);
    
    exp.exec = function (string) {
        var executed = RegExp.prototype.exec.call(this, string),
            i;
        
        if (executed === null) {
            return null;
        }
        
        for (i = 1; i < executed.length; i++) {
            if (__isNamed[i - 1]) {
                executed[__namedGroups[i - 1]] = executed[i];
            }
        }
        
        return executed;
    };


    return exp;
};


console.log(namedRegExp("(?<what>[a-z]+):(?'number'[0-9]+)(.*)").exec("id:64a"));
console.log(namedRegExp("(?P<hours>[0-1][0-9]|2[0-3]):(?<minutes>[0-5][0-9])").exec("22:21"));