简单的JavaScript String.replace.call导致“InternalError:太多的递归”

时间:2010-01-24 10:08:21

标签: javascript

给出以下JavaScript“类”定义:

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;
        }
    });
};

您能否详细解释为何下面打电话给toString() ...

var q1 = new Quota(60);
console.log( q1.toString() );

...导致出现以下错误:

  

InternalError :过多的递归{   message =“太多的递归”,   更...}

我在Firebug控制台中运行代码(Firefox 3.5.7 + Firebug 1.5)。理想情况下,我想知道递归回调到toString()的位置以及您如何通过callapply

执行替换功能的建议

1 个答案:

答案 0 :(得分:5)

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

format.replace尝试调用this.toString,它以无限递归结束。根据要求,这是一个证据: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');

请改为尝试:

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

修改

除了问题之外,我发现允许函数访问当前配额的最好方法是在它的闭包之外创建一个变量:

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;
    });
};