RegExp methods and lastIndex

By default, if your RegExp is global (that is, uses the g flag), the RegExp methods (that is, test() and exec()) will mutate the lastIndex property of the RegExp object upon each execution. These methods will attempt to match the subject string from the index specified by the current lastIndex property, which is 0 by default, and will then update the lastIndex upon every subsequent call.

This can lead to unexpected behavior if you expect exec() or test() to always return the same result for a given global regular expression and string:

const alphaRegex = /[a-z]+/g;

alphaRegex.exec('aaa bbb ccc'); // => ["aaa"]
alphaRegex.exec('aaa bbb ccc'); // => ["bbb"]
alphaRegex.exec('aaa bbb ccc'); // => ["ccc"]
alphaRegex.exec('aaa bbb ccc'); // => null

It will also lead to confusion if you attempt to execute a global regular expression on more than one string without resetting the lastIndex yourself:

const alphaRegex = /[a-z]+/g;

alphaRegex.exec('monkeys laughing'); // => ["monkeys"]
alphaRegex.lastIndex; // => 7
alphaRegex.exec('birds flying'); // => ["lying"]

As you can see, following the match with the "monkeys" substring, the lastIndex is updated to the next index (7),  which means, when executed on a different string, the regular expression will continue where it left off and attempt to match everything beyond that index, which in the case of the second string, "birds flying", is the substring "lying".

As a rule, to avoid these confusions, it's important to always have ownership over your regular expressions. Don't accept regular expressions from elsewhere in a program if you're using RegExp methods. Also, don't attempt to use exec() or test() on different strings without resetting the lastIndex before each execution:

const petRegex = /(?:dog|cat|hamster)/g;

// Testing multiple strings without resetting lastIndex:
petRegex.exec('lion tiger cat'); // => ["cat"]
petRegex.exec('lion tiger dog'); // => null

// Testing multiple strings with resetting lastIndex:
petRegex.exec('lion tiger cat'); // => ["cat"]
petRegex.lastIndex = 0;
petRegex.exec('lion tiger dog'); // => ["dog"]

Here, you can see that, if we don't reset the lastIndex, our regular expression fails to match on subsequent strings that are passed to the exec() method. If, however, we reset the lastIndex prior to each subsequent exec() call, we'll observe a match. 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.13.164