Modern JavaScript: Symbols Are Metadata
Welcome to the Symbols Are Metadata lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Before JavaScript had symbols, object property names were always strings, which was nice and simple. Now they can be strings or symbols. Why bother adding this complication?
The answer is that symbols let us draw an important distinction: symbols are "out of band data", or "metadata". They're not a normal part of the object.
For example, when we serialize an object with
JSON.stringify, symbol properties are ignored completely. Only the regular string properties are serialized. If weJSON.stringifyand thenJSON.parsethe result back into an object, none of the symbol properties will remain.>
const user = {[Symbol.toStringTag]: 'Amir'};JSON.parse(JSON.stringify(user));Result:
>
const user = {name: 'Amir',[Symbol.toStringTag]: 'Amir'};JSON.parse(JSON.stringify(user));Result:
{name: 'Amir'}Symbols help us to enforce conceptual separation in our systems by distinguishing data from metadata, and not just when we call
JSON.stringify. Some properties on an object are regular data, which is directly relevant to something that a user does with the system. For example, aCommentobject might have a title, a message, and an associated thread.Other properties are metadata, relevant only to the internals of the application. These should never be visible to users. Metadata might include database record creation times, or which database connection the record came from, or the logger object that they log to. Depending on our database's design, database records' IDs might be also considered metadata that should never be visible to users.
Symbols help us separate the data from the metadata. If we ever find ourselves trying to show metadata properties to a user, that's a strong signal that we're making a mistake.