Symbols Are Your Friend Series Part VI: Symbol.match, Symbol.matchAll & Symbol.replace
Tags: javascript
Published: 2020-11-10 19:26:07

<b>Symbols Are Your Friend Series</b>
  - [Part I: A Gentle Introduction](https://dev.to/js_bits_bill/symbols-are-your-friend-a-gentle-introduction-js-bits-23af)
  - [Part II: Symbol.for() & Symbol.keyFor()](https://dev.to/js_bits_bill/symbols-are-your-friend-part-ii-symbol-for-symbol-keyfor-js-bits-3clc)
  - [Part III: Symbol.iterator](https://dev.to/js_bits_bill/symbols-are-your-friend-part-iii-symbol-iterator-js-bits-18c4)
  - [Part IV: Symbol.search, Symbol.split, & Symbol.species](https://dev.to/js_bits_bill/symbols-are-your-friend-part-iv-symbol-search-symbol-split-symbol-species-js-bits-4i25)
  - [Part V: Symbol.toPrimitive, Symbol.toStringTag, & Symbol.unscopables](https://dev.to/js_bits_bill/symbols-are-your-friend-part-v-symbol-toprimitive-symbol-tostringtag-symbol-unscopables-js-bits-nee)

---

Well, we've made it this far 😅. We might as well explore the remaining Symbol properties. There's only 6 more left, but we'll break them up into 2 more articles. Today we'll look at:

<ul>
  <li><code>Symbol.match</code></li>
  <li><code>Symbol.matchAll</code></li>
  <li><code>Symbol.replace</code></li>
</ul>

---

<b><code>Symbol.match</code></b>
This symbol defines the matching behavior of a regular expression against a string. Here are 2 interesting ways this can be used:

The first way allows us to override the internal check within certain String methods (like <code>.startsWith()</code>, <code>.includes()</code>, etc.) that check if the first argument is erroneously an regular expression. This internal check uses the <code>match</code> property so if we simple set it to false we can make our regex act as if it's not a regex and use those String methods:
```js
const myRegex = /abc/;
'/abc/'.startsWith(myRegex); // Throws error

// Override myRegex to not be treated as a regular expression
myRegex[Symbol.match] = false;
'/abc/'.startsWith(myRegex); // true
```

The other way we can use <code>Symbol.match</code> is similar to some of the other well-known symbols we've seen already like <code>Symbol.split</code>:
```js
const myRegex = /abc/;
myRegex[Symbol.match] = function(string) {
  const index = string.search(this);
  if (index > -1) return `Match found @ index ${index}`;
  return 'No match found';
};

'I know my 123\'s'.match(myRegex); // Returns "No match found"
```
---

<b><code>Symbol.matchAll</code></b>
This symbol is a method that returns an iterator of results when you match a regular expression against a string. Before we check this out, note that there's already a <code>String.prototype.matchAll()</code> method that does the inverse: it matches a string against a regular expression:

```js
const myRegex = /wood/g;
const str = 'How much wood would a woodchuck chuck?';

for (result of str.matchAll(myRegex)) {
  console.log(result);  // Logs matches
}
```
So with <code>Symbol.matchAll</code> we can essentially swap the calling object and argument types:

```js
const myRegex = /wood/g;
const str = 'How much wood would a woodchuck chuck?';

for (result of myRegex[Symbol.matchAll](str)) {
  console.log(result); // Logs matches
}
```
<code>RegExp.matchAll()</code> would otherwise throw a TypeError.

---
<b><code>Symbol.replace</code></b>
This symbol defines the behavior for the <code>.replace()</code> method on a string.

Default behavior:
```js
const spoonRegex = /spoon/;

const result = 'There is no spoon'.replace(spoonRegex, 'fork');
console.log(result); // Logs "There is no fork"
```

<code>Symbol.replace</code> modification:
```js
const spoonRegex = /spoon/;
spoonRegex[Symbol.replace] = function(string, replacement) {
  const match = string.match(this) || [];
  const index = match.index;

  if (!match.length) return string;
  return `${string.slice(0, index)}${replacement}, lol`;
};

const result = 'There is no spoon'.replace(spoonRegex, 'fork');
console.log(result); // Logs "There is no fork, lol"
```

----------
Check out more #JSBits at my blog, [jsbits-yo.com](http://jsbits-yo.com/). Or follow me on [Twitter](https://twitter.com/JS_Bits_Bill).