Javascript Symbols
Tags: javascript, webdev, learning, coding
Published: 2024-06-13 06:24:30

The good perk of having a lot of people who code around you is that you end up discussing things that you don't get to see on a day-to-day basis as a simpleton frontend developer.

This time, I landed on the __concept of symbols in JavaScript__, which is something I don't have to deal with at work, but something that JavaScript offers and it'd be nice to understand what it is and why it is :D

## What is a Symbol?

__A symbol is a unique and immutable data type in JavaScript__.

If that doesn't tell you anything (which indeed didn't for me), know that a symbol is one of the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#primitive_values" target="_blank">JavaScript primitive data types</a> just as string, boolean, integer etc. but it works like a *special identifier to access object properties*, and it can be used more or less like a property key.

Let's imagine that we have an object where we store a person's `name`, an `id` and their `age`.

```javascript
let person = {
  name: "Sophia",
  id: 12345678,
  age: 24, // (yes, I'm a trailing comma person)
};
```

If we want to access the value of the `id` property, we'd just do:

```javascript
console.log(person.id); // will give us 12345678
```

It is fair to assume that `id` won't change as often as the other characteristics of a person, and tailor our work around that assumption.

Let's try to use a symbol as a key by creating it. This can be done using the `Symbol()` constructor:

```javascript
let symbolIDKey = Symbol("id");
let person = {
  name: "Sophia",
  [symbolIDKey]: 12345678,
  age: 30,
};
console.log(person[symbolIDKey]); // outputs 12345678
```

You could, in theory, use no `"id"` parameter (properly referred as __descriptor__), but if you were to use more than one symbol key, it'd be more challenging to know which is which.

## Why symbols then?

Using symbols as object keys will provide you with a unique and guaranteed way of accessing object properties, __even if other code adds or modifies properties with the same key__.

For example:

```javascript
let symbolIDKey = Symbol("id");
let person = {
  name: "Sophia",
  [symbolIDKey] = 12345678,
  age: 30,
};
```

Some other code, for whatever reason, will try to do

```javascript
person.id = 00000000;
```

You will be left with

```javascript
let symbolIDKey = Symbol("id");
let person = {
  name: "Sophia",
  [symbolIDKey] = 12345678,
  age: 30,
  id: 00000000,
};

console.log(person.id); // will output 00000000
console.log(person[symbolIDKey]); // will output our more expected 12345678
```

The symbol key is allowing us to preserve the original value even if some other code might try to alter the property `id`.

> With symbols you can add private properties to an object that are not intended to be modified or accessed directly by other code.

But beware! Symbols keys are not enumerated, which means that __they do not show up in the list of keys of the object__ if you try to access them by loops and mappings.

You cannot even access the symbol keys of an object with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys" target="_blank" rel="norefferer noopener">`keys()`</a> nor with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames" target="_blank" rel="norefferer noopener">`getOwnPropertyNames()`</a>!

You will need to be aware of the structure of your object and if you need to access the symbol keys, you'll have to use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols" target="_blank" rel="norefferer noopener">`getOwnPropertySymbols()`</a>.

...

And that's it! I don't see myself using this approach anytime soon, but it's good to know that, should I be concerned with the integrity of the data I work with, there are ways for me to preserve some information in the flimsy world that JavaScript often creates for us.

## Sources and inspiration
- <a href="https://chat.openai.com/" target="_blank">ChatGPT</a> prompt: `Act like a senior software developer mentor. Explain to me in the simplest way possible what javascript Symbols are, making very basic examples that DO NOT use "foo" "bar" words. Make small sentences and ask me often if I am able to understand. Thank you.`
- <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol" target="_blank">Symbol</a> from <a href="https://developer.mozilla.org/en-US/" target="_blank">mdn web docs</a>
- <a href="https://flaviocopes.com/javascript-symbols/" target="_blank">JavaScript Symbols</a> from <a href="https://flaviocopes.com/" target="_blank">Flavio copes</a>
- Cover: <a href="https://www.freepik.com/free-psd/3d-female-character-reading-book_13678507.htm" target="_blank">Person sitting on books</a> and <a href="https://www.freepik.com/free-vector/realistic-3d-shapes-floating-background_13397766.htm" target="_blank">Background 3d composition</a> by <a href="https://www.freepik.com/author/freepik" target="_blank">Freepik</a>, <a href="https://www.freepik.com/free-psd/website-coding-icon-3d-illustration_28638422.htm" target="_blank">Cute round interface</a> by <a href="https://www.freepik.com/author/ekayasadesign" target="_blank">Ekayasa.Design</a>
<hr />
Originally posted in <a href="https://oh-no.ooo">oh-no.ooo</a> (<a href="https://www.oh-no.ooo/articles/javascript-symbols">JavaScript Symbols</a>), my personal website.