关于string.replace的相同代码在Firefox和chrome中得到不同的结果

时间:2018-11-26 03:21:02

标签: javascript google-chrome firefox replace

最近我写了一个简单的javascript代码,但是在Firefox和Chrome中出现了一个很奇怪的行为,代码列表如下:

console.log(
  "sap.ui.widget.Progressbar"
    .replace(/\./g, '/')
    .replace("", "./resources/css/")
);

在Chrome(版本69.0.3497.100)中,我得到了预期的结果:“ ./ resources / css / sap / ui / widget / Progressbar”,但是在Firefox(版本63.0)中,我得到了完全不同的结果:“ sap / ui / widget / Progressbar”。

能不能解释一下?这是Firefox的错误吗?谢谢。

1 个答案:

答案 0 :(得分:0)

是的,这是Spidermonkey中的错误。如果一切顺利,它将has been reported保留在FF 65中,将成为fixed。 (其他任何Javascript引擎上的错误does not occur

问题在于,超过24个字符的中间字符串(例如由在字符串文字上调用String.prototype.replace导致的中间字符串)在Spidermonkey中表示为ropes,而那23个或更少的字符不是绳索。当用replace(''调用时,Spidermonkey没有正确替换绳索。 (请参见js/src/builtin/String.cpp中的函数BuildFlatRopeReplacement

您可以通过调用.replace并用24个以上的字符串替换至少一个字符,然后用空字符串再次调用.replace来重现该问题:

// Run on FF 64 or lower to reproduce:

// Second replacement at the beginning of the string fails:
console.log(
  "a".repeat(24).replace('a', 'b').replace("", "foo")
);

// Works as expected:
console.log(
  "a".repeat(23).replace('a', 'b').replace("", "foo")
);