RegExp.prototype.global

Returns whether the regular expression was created with the g flag.

Signature
get RegExp.prototype.global
  • Added in JavaScript ES3 (1999)

Return value

booleantrue if the g flag is set, false otherwise.

Errors

TypeError if accessed on a value that is not a RegExp object (other than RegExp.prototype itself).

Changelog

  • PHP ES6global became an accessor on RegExp.prototype instead of an own data property of each instance, so reading it on a non-RegExp receiver now throws.
  • PHP ES2020String.prototype.matchAll() and replaceAll() were added and throw a TypeError when handed a non-global regex.

global reports one bit: is the g flag present? Its value is fixed at construction and read-only, so it is a query, not a switch.

What g changes

The flag decides both how much of the string is processed and whether the regex keeps state. String.prototype.replace() substitutes only the first match without it and every match with it. match() returns a full result array with capture groups without it, but a flat array of matched strings with it — a genuinely different return shape. matchAll() and replaceAll() refuse to run at all without it, throwing a TypeError.

The flag also turns on lastIndex tracking, which is why a global regex reused across calls appears to skip matches.

Where the property earns its keep

Guard code that accepts a regex from a caller. Before iterating, check re.global and, if it is false, build a clone with new RegExp(re.source, re.flags + "g") rather than mutating the caller's object. That is exactly the contract matchAll() enforces by throwing.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Guard a helper that accepts a caller-supplied regex before calling matchAll
  • Explain why replace() only changed the first occurrence
  • Decide whether a regex needs its lastIndex reset before reuse

Frequently asked questions

Why does replace() only change the first match?

Because the regex has no g flag. Add it — "a-a".replace(/a/g, "X") — or use String.prototype.replaceAll(), which requires a global regex when given one and accepts plain strings otherwise.

Can I set the global property to true?

No, it is a read-only getter. Build a new regex with the flag included: new RegExp(re.source, re.flags + "g"), guarding against a duplicate if the flag is already there.

What is the difference between the g and y flags?

Both enable lastIndex tracking, but g searches forward from lastIndex for the next match anywhere, while y requires the match to begin exactly at lastIndex and fails immediately otherwise.

More examples

Normalising a caller's regex

Cloning rather than mutating means the caller's regex keeps its own flags and lastIndex. Both call styles now return the same count instead of one of them throwing.

Example · javascript
function countMatches(re, str) {
  const g = re.global ? re : new RegExp(re.source, re.flags + "g");
  return [...str.matchAll(g)].length;
}

console.log(countMatches(/a/, "banana"));  // 3
console.log(countMatches(/a/g, "banana")); // 3

const caller = /a/;
countMatches(caller, "banana");
console.log(caller.global, caller.lastIndex); // false 0 - untouched

g changes what match() returns

Without g, match() returns one result array carrying index, input and the capture groups. With g it returns a flat list of matched strings and discards the groups — code that reads m[1] breaks when someone adds the flag.

Example · javascript
const re = /(\w)(\d)/;
const str = "a1 b2";

console.log(str.match(re));               // full result + groups
console.log(str.match(new RegExp(re.source, "g"))); // [ "a1", "b2" ]

console.log("aaa".replaceAll(/a/g, "b")); // "bbb"
try { "aaa".replaceAll(/a/, "b"); }
catch (e) { console.log(e.name); }

Discussion

  • Be the first to comment on this lesson.