⚠️ The answer to your question follows, but please note that in 2019 you should probably not be using this code. See the end of my answer for a better solution. ⚠️
Regexper does a pretty good job of demonstrating what this regular expression will match:

In English, you can read this as:
- One or more
?
or &
characters, followed by
- group #1: one or more characters that aren't
=
or &
, followed by
- an
=
, followed by
- group #2: zero or more characters that aren't
&
Group #1 captures the parameter names and group #2 captures their values.
As for the callback function (function(a,key,value) { ...
) passed to replace
, let's ask MDN:
You can specify a function as the second parameter. In this case, the function will be invoked after the match has been performed. The function's result (return value) will be used as the replacement string. … Note that the function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global.
The arguments to the function are as follows:
match
– The matched substring.
p1, p2, ...
– The nth string found by a parenthesized capture group, provided the first argument to replace()
was a RegExp
object.
- …
(Source: MDN: String.prototype.replace
– Specifying a function as a parameter)
(I've omitted the rest as it doesn't pertain to our question.)
What this tells us is that the function is called for every match, i.e. every parameter name-value pair in the string, and that the second argument (p1
, or key
in your code) holds the string captured by group #1 and the third argument (p2
/value
) holds the string captured by group #2.
The code you've found is really using replace
for its side-effect: It's a really simple way to iterate all of the matches in a string.
A better way
As noted in the blog post you linked to, if you're targeting current browsers, instead of parsing the query string manually you should use URLSearchParams, which is intended for this exact purpose:
const query = '?foo=1&bar=2';
const searchParams = new URLSearchParams(query);
// Get a specific param
const foo = searchParams.get('foo');
console.log('got foo:', foo);
// Iterate over all params
searchParams.forEach((val, key) => console.log(key, 'is', val));
URLSearchParams works in all modern browsers, including MS Edge ≥ 17 (but not IE). The also exist polyfills for older browsers.