1 of 8

String#replaceAll

2 of 8

// → 'bbb'

'aaa'.replaceAll('a', 'b');

3 of 8

  • option: 'bbb' // auto-g any non-global RegExp ("replace all")
  • option: 'baa' // lack of g flag wins; matches matchAll
  • option: TypeError // only accept strings in replaceAll
    • note: forward-compatible; does not prevent us from accepting RegExp later
  • option: TypeError // disallow non-global RegExps in replaceAll
    • note: forward-compatible; does not prevent us from accepting later
  • option: rename method to avoid the need to match replace or matchAll
    • replaceEvery? substitute*?
  • option: add an optional options bag to replace instead
    • 'aaa'.replace('a', 'b', { all: true })
    • but then, same problem: how does it behave with a non-global regexp?

'aaa'.replaceAll(/a/, 'b');

4 of 8

  • proposal: TypeError // disallow non-global RegExps in replaceAll & matchAll
    • note: forward-compatible; does not prevent us from accepting later

'aaa'.replaceAll(/a/, 'b');

5 of 8

  • crbug.com/v8/9551 added back in July
  • counts usage of matchAll with a non-global RegExp
  • extremely low use counts
  • we believe it's web-compatible to change String.prototype.matchAll to throw on non-global RegExps

V8/Chromium UseCounter

6 of 8

// The stickiness gotcha (example by Richard Gibson)

'No Uppercase!'.replaceAll(/[A-Z]/g, ''); // 'o ppercase!'

'No Uppercase?'.replaceAll(/[A-Z]/gy, ''); // 'o Uppercase?'

'NO UPPERCASE!'.replaceAll(/[A-Z]/gy, ''); // ' UPPERCASE!'

7 of 8

  • change String.prototype.matchAll to throw for non-global RegExp arguments
  • change String.prototype.replaceAll accordingly, i.e. throw for non-global RegExp searchValues
  • keep sticky behavior as-is, for consistency with String.prototype.replace
  • advance String.prototype.replaceAll to stage 3

Proposal for today

8 of 8

Stage 3?