I'm working on an ES6 app that sends some of its data over the network. Part of this involves identifiers that are implemented as ES6 Symbol
s. For example:
const FOO = Symbol('foo');
Calling Foo.toString()
yields Symbol(foo)
. When I pass these over the network, I'd like to pass it as just foo
. However, to my knowledge, there is no way to extract foo
from Symbol(foo)
other than to pull it out with a regular expression (specifically, /^Symbol\((.*)\)$/
).
Should I rely on the regular expression always matching? Or is it possible that future updates to ES6 will break this? If I can't rely on the regex matching then I'll just send it over the wire as Symbol(foo)
.
According to the spec it’s always "Symbol(" + description + ")"
.
Symbol.prototype.toString
returns a string from an internal method call to SymbolDescriptiveString(sym)
:
Let desc be sym’s
[[Description]]
value.
If desc isundefined
, let desc be the empty string.
[…]
Return the string-concatenation of"Symbol("
, desc, and")"
.
Now, updating this answer in 2019, you have two options:
Use (or polyfill) Symbol.prototype.description
, which is part of ECMAScript 2019 and is supported by all modern JavaScript engines:
const foo = Symbol("foo"),
bar = Symbol.for("bar"),
iter = Symbol.iterator;
console.log(foo.description); // "foo"
console.log(bar.description); // "bar"
console.log(Symbol.iterator.description); // "Symbol.iterator"
Or use Symbol.prototype.toString
like so:
const foo = Symbol("foo"),
bar = Symbol.for("bar"),
iter = Symbol.iterator;
console.log(foo.toString().slice(7, -1)); // "foo"
console.log(bar.toString().slice(7, -1)); // "bar"
console.log(iter.toString().slice(7, -1)); // "Symbol.iterator"
// Or without “magic numbers”:
console.log(foo.toString().slice("Symbol(".length, -")".length)); // "foo"
console.log(bar.toString().slice("Symbol(".length, -")".length)); // "bar"
console.log(iter.toString().slice("Symbol(".length, -")".length)); // "Symbol.iterator"
Since the strings surrounding the description are fixed, slice
is a good option to use, especially because a symbol description could itself contain parentheses, line breaks, the string "Symbol"
, etc, and the .
in the regular expression won’t match line breaks for example.