1

I refer to the MDN Documentation for Javascript here.

It says the following RegExp properties are deprecated:

$1-$9
$_
$*
$&
$+
$`
$'
input
lastMatch   
lastParen   
leftContext 
rightContext    

Why have they become deprecated? Aren't they all useful properties? What are the new replacements, if any?

Specifically, the documantation says:

"The following properties are deprecated. This does not affect their use in replacement strings."

Doesn't that sound self-contradictory?

Chong Lip Phang
  • 8,755
  • 5
  • 65
  • 100
  • 1
    What were you hoping to use them for? It's more useful to know what to use instead, but it's hard to say without knowing what you're doing. – loganfsmyth Jul 16 '17 at 03:33
  • The problem is that they are *global* (static) properties, assigned from method calls on regex instances. That includes leaking information, changing value at unexpected times and in general leading to buggy behaviour and unreadable code. – Bergi Jul 16 '17 at 04:31

1 Answers1

3

They are deprecated because it an API that is hard to use correctly and leaks information. When you do a match on a regex, generally you expect a value to be returned by the matching function, or at least tracked on the RegExp instance itself. To be clear, these are properties of RegExp, not of instances. Take this example:

var re = /([0-9])([0-9])([0-9])/;
re.test("345");
var three = RegExp.$1;
var four = RegExp.$2;
var five = RegExp.$3;

that is a seriously ugly API.

Not only is it hard to use, but it means that if you are writing a library, things could access internal state of your API. There are other dangers in this example, but consider a case like:

matchPrivateKey();
var private = RegExp.$1;

If inside matchSecretKey you used a regex to match some private key, it is now accessible outside of your module and leaked to other code running on the page.

It is much nicer to use an API like

var re = /([0-9])([0-9])([0-9])/;
var [, three, four, five] = "345".match(re);

where .match returns an array with the matched results.

There is never a time where you'd expect an object instance to mutate properties on the constructor function.

"The following properties are deprecated. This does not affect their use in replacement strings."

Doesn't that sound self-contradictory?

Not at all. The properties on RegExp are deprecated, but doing "345".replace(/3([0-9])5/, '$1') is still totally find since a string pattern is unrelated to the constructor property.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • `RegExp.$1` up to `RegExp.$9` seems to be a leftover from the original Perl API, since `$1` up to `$9` are special builtin context sensitive variables in the language. I'm guessing Mozilla wanted to make it feature compatible to enable existing workflows, but then later deemed it unnecessary. – Electric Coffee Feb 27 '23 at 08:15