Check if value is a Symbol in JavaScript
In ES 2015 and up, typeof x === 'symbol'
is all that's needed. But it won't work if you're transpiling your code to ES 5.1 or earlier, even if you're using a polyfill for the Symbol
builtin.
Every polyfill I've seen, including the babel-polyfill, implements Symbol as an object (i.e. typeof x === 'object'
) using a constructor function called Symbol
. So in those cases you can check that Object.prototype.toString.call (x) === '[object Symbol]'
*.
Putting it all together, then, we get:
function isSymbol (x) { return typeof x === 'symbol' || typeof x === 'object' && Object.prototype.toString.call (x) === '[object Symbol]';}
*Note that I'm not using instanceof
in the transpiled scenario. The problem with instanceof
is that it only returns true for objects that were created within the same global context as the assertion being made. So if, say, a web worker passes a symbol back to your page, or symbols are passed between iframes, then x instanceof Symbol
will return false! This has always been true of all object types, including the builtins. instanceof
often works just fine, but if there's any chance of your code being in a "multi-frame" scenario as I've described, use with caution!
The most efficient way is to test the constructor of a value:
const result = (value && value.constructor === Symbol);