You can't set new properties on JavaScript Symbols

2 min read

This post is part of my Today I learned series in which I share all my learnings regarding web development.

Symbols are these relatively new types that were added to the language not too long ago. I have to say though that I'm not using them very often. Let's quickly recap with an MDN quote:

Every symbol value returned from Symbol() is unique. A symbol value may be used as an identifier for object properties; this is the data type's only purpose.

And this is how they work (shamelessly copied from MDN):

const symbol1 = Symbol();
const symbol2 = Symbol(42);

console.log(typeof symbol1);
// expected output: "symbol"

console.log(symbol3.toString());
// expected output: "Symbol(foo)"

Look like "normal" objects in JavaScript, right? Everything is an object in JavaScript anyways but today I discovered something odd. What happens when I want to set a new property on a symbol? (if that's a good thing to do is another question)

const a = Symbol();
a.foo = 'bar';
console.log(a.foo); // ?

The snippet above logs undefined to the console. This shows that it is not possible to set new properties on a symbol. The runtime is not throwing an error though.

The reason for that behavior is that symbols are primitives in JavaScript and primitives are immutable. This means the same functionality applies for the types Boolean, Null, Undefined, Number and String.

const a  = 123;
a.foo = 'bar';
console.log(a.foo);    // undefined

const b = 'baz';
b.length = 2;
console.log(b.length); // 3

There are clearly not many use cases for setting a new or redefining a property on an e.g. Number (if there are any at all) but I didn't know that primitives are immutable in general and that's a nice nitty gritty detail of JavaScript to know.

Edited: As the reddit user pertheusual points out adding properties to primitives throws an exception in strict mode.

Load time