开发者

Simple JavaScript String.replace.call results in "InternalError: too much recursion"

Given the following JavaScript "class" definition:

var Quota = function(totalMinutes){
    this.totalMinutes = parseInt(totalMinutes || 0, 10);
};

Quota.prototype.valueOf = function(){
    return this.totalMinutes;
};

Quota.prototype.toString = function(format){
    format = format || "hh:mm";

    return format.replace.call(this, /hh?|mm?/g, function(match){
        switch (match) {
            case "hh":
                return this.totalMinutes * 60;
            case "mm":
                return this.totalMinutes;
        }
    });
};

Can you please explain exactly why the below call to toString()...

var q1 = new Quota(60);
console.log( q1.toStri开发者_运维问答ng() );

...results in the following error being raised:

InternalError: too much recursion { message="too much recursion", more...}

I'm running the code (Firefox 3.5.7 + Firebug 1.5) in the Firebug Console. Ideally I'd like to know where is the recursive call back to toString() and your suggestions for how the replace function could be executed here via call or apply


return format.replace.call(this, /hh?|mm?/g, function(match)

format.replace tries to call this.toString, which ends in an infinite recursion. As requested, here's a proof this happens: http://jsbin.com/eweli/:

var Quota = function(totalMinutes){
    this.totalMinutes = parseInt(totalMinutes || 0, 10);
};

Quota.prototype.toString = function(format){
    alert ("Quota.prototype.toString is called");
};

var q1 = new Quota(60);
var a = "string".replace.call(q1,'hello','world');

Try this instead:

return format.replace(/hh?|mm?/g, function(match)

Edit

Problems aside, the best way I've found to allow the function to access the current quota is to create a variable outside it's closure:

Quota.prototype.toString = function(format){
    format = format || "hh:mm";
    var quota = this;
    return format.replace(/hh|mm/g, function(match){
        switch (match) {
            case "hh":
                return quota.totalMinutes / 60;
            case "mm":
                return quota.totalMinutes;
        }
        return match;
    });
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜