---
title: "Well-known Symbols"
description: "A deep dive into Well-known Symbols in JavaScript. Practical notes and code examples on Well-known Symbols by Hemanth HM."
url: "https://h3manth.com/scribe/well-known-symbols/"
canonical_url: "https://h3manth.com/scribe/well-known-symbols/"
markdown_url: "https://h3manth.com/scribe/blog/well-known-symbols.md"
publishDate: "2023-02-14T00:00:00.000Z"
author: "Hemanth HM"
category: "javascript"
tags: ["javascript","symbols","es6"]
word_count: 683
reading_time_minutes: 4
x_markdown_tokens: 1314
content_signal: "ai-train=yes, search=yes, ai-input=yes"
---

# Well-known Symbols

> A deep dive into Well-known Symbols in JavaScript. Practical notes and code examples on Well-known Symbols by Hemanth HM.

I was recently asking on public forums if people can name at least three Well-known Symbols in JavaScript without looking up and few could. Let's explore these powerful tools!

## Symbol.isConcatSpreadable

This symbol is used to determine if an object should be flattened when concatenated with other objects. It can be used to change the behavior of the `Array.prototype.concat` method.

```javascript
const arr1 = [1, 2, 3];
const spreadable = {
  [Symbol.isConcatSpreadable]: true,
  0: 4,
  1: 5,
  2: 6,
  length: 3
};

console.log([].concat(arr1, spreadable)); // [1, 2, 3, 4, 5, 6]
```

## Symbol.species

This symbol is used to specify the constructor to use when creating derived objects. It can be used to customize the behavior of built-in methods that create new objects.

```javascript
class MyArray extends Array {
  static get [Symbol.species]() {
    return Array;
  }
}

const myArray = new MyArray(1, 2, 3);
const mappedArray = myArray.map(x => x * 2);

console.log(mappedArray instanceof MyArray); // false
console.log(mappedArray instanceof Array);   // true
```

P.S: this functionality may be removed in the [future](https://github.com/tc39/proposal-rm-builtin-subclassing).

## Symbol.match

This symbol is used to determine the value to search for when using the `String.prototype.match` method. It can be used to change the behavior of the `match` method for RegExp-like objects.

```javascript
const myRegex = /test/;
'/test/'.startsWith(myRegex); // Throws TypeError

const re = /foo/;
re[Symbol.match] = false;

"/foo/".startsWith(re); // true
"/bar/".endsWith(re);   // false
```

P.S: The presence of that symbol is what marks an object as "being a regex".

```javascript
const myRegex = /foo/g;
const str = 'How many foos in the the foo foo bar?';

for (result of myRegex[Symbol.matchAll](str)) {
  console.log(result); // we will get the matches
}
```

## Symbol.replace

This symbol is used to determine the replacement value when using the `String.prototype.replace` method. It can be used to change the behavior of the `replace` method for RegExp-like objects.

```javascript
const customReplace = str => str.replace(/\d+/g, match => `-${match}-`);

const customString = {
  [Symbol.replace]: customReplace
};

const originalString = "foo123bar456baz";
const result = originalString.replace(customString, '*');

console.log(result); // outputs "foo-123-bar-456-baz"
```

## Symbol.search

This symbol is used to determine the value to search for when using the `String.prototype.search` method. It can be used to change the behavior of the `search` method for RegExp-like objects.

```javascript
const customSearch = str => str.search(/\d+/);

const customRegExp = {
  [Symbol.search]: customSearch
};

const string = "foo123bar456baz";
string.search(customRegExp); // outputs 3
```

## Symbol.split

This symbol is used to determine the value to split when using the `String.prototype.split` method. It can be used to change the behavior of the `split` method for RegExp-like objects.

```javascript
const customSplit = str => str.split(/\d+/);

const customRegExp = {
  [Symbol.split]: customSplit
};

const string = "foo123bar456baz";
string.split(customRegExp); // outputs [ 'foo', 'bar', 'baz' ]
```

## Symbol.unscopables

This symbol is used to determine the properties of an object that should be excluded from the scope of `with` statements. It can be used to change the behavior of with statements.

```javascript
const person = {
  age: 42
};

person[Symbol.unscopables] = {
  age: true
};

with (person) {
  console.log(age);
  // Expected output: Error: age is not defined
}
```

## Symbol.dispose

Explicit Resource Management refers to a system in which the user manages the lifespan of a "resource" explicitly, either by using imperative methods (such as `Symbol.dispose`) or declarative methods (such as `using` a block-scoped declaration).

```javascript
{
  console.log(1);
  using {
    [Symbol.dispose]() {
      console.log(2);
    }
  };
  console.log(3);
}
// will log 1, 3, 2
```

---

This informational blog aimed to impart a deeper understanding of the well-known symbols intrinsic to the JavaScript language. These symbols, such as Symbol.iterator, Symbol.toStringTag, and Symbol.for, represent sophisticated and versatile instruments that can be utilized to augment and regulate the behavior of code.

Acquiring a comprehensive understanding of the available symbols within the JavaScript environment is crucial in the development of high-performing, maintainable, and scalable applications. Hence, it is recommended that during the conceptualization and implementation phase of a project, one evaluates the feasibility of incorporating these symbols, to streamline the code and achieve desired outcomes in a more sophisticated and elegant manner.

Thanks to [@ljharb](https://twitter.com/ljharb?lang=en) for a quick review on this post.
