« Bugzilla Issues Index

#1433 — String.prototype.replace calls function even if no match was found

Change algorithm to stop after step 8 if no match was found to ensure compatibility with ES5.

Also remove assertion in step 5 to handle case when RegExp.prototype.@@isRegExp has been removed.

And two additional typos in Table 33:
"emptry" -> "empty" (twice!) and "stringLenth" -> "stringLength"

And for the implementation-defined notes, see bug 1133. Test262 already tests for a certain implementation.

fixed in rev 15 editor's draft.

Regarding the implementation-defined behavior. Is there any variation among existing major implementations?

Simply returning after step 8 may not be the right solution due to side effects:
"a".replace("b", {toString: function(){throw 0}})
"a".replace(/b/, {toString: function(){throw 0}})

All major browsers throw an exception for the second call (search value is RegExp). For the search value is String case, JSC and V8 behave differently compared to the others, i.e. they do not throw an exception.


Concerning the implementation-defined behaviour question:

Based on the source code at [1,2,3], SpiderMonkey, V8 and JSC all seem to share the same behaviour. Opera seems to be compliant as well, checking the actual source code may be beneficial, though. IE10 has an extension where $0 (and $00) refer to the entire matched pattern, e.g. "ab".replace(/(a)b/, "$1_$01_$0_$00") === "a_a_ab_ab".

For the case where the referenced capture does not exist, the behaviour seems to be the same across all major browsers (also see referenced source code from SM/V8/JSC):

"ab".replace("a", "$2") === "$2b"
"ab".replace(/(a)/, "$2") === "$2b"
"a".replace(/((((((((((a))))))))))/, "$9_$09_$10_$11") === "a_a_a_a1"

Maybe it was allowed to be implementation defined for older SpiderMonkey versions [4], but since [5] SpiderMonkey works like the others. Based on [6], Netscape Navigator also had some quirks, but that isn't important anymore, is it?


resolved in rev 15, May 14, 2013 draft