How Lodash isSymbol Validates Custom Symbols

This article examines how the Lodash utility library validates JavaScript symbols through its _.isSymbol function, addressing whether runtime symbol registries are involved in the check. While developers often associate symbol storage with registries like the Global Symbol Registry, Lodash bypasses registry lookups entirely. Instead, it relies on strict primitive type inspection and internal prototype tags to validate both standard and custom symbols instantaneously.

The Role of Symbol Registries in Lodash

When working with JavaScript symbols, the ECMAScript specification provides the Global Symbol Registry, accessible via methods like Symbol.for() and Symbol.keyFor(). This runtime registry holds shared symbols across execution contexts such as iframes or service workers.

However, _.isSymbol polls zero symbol registries. It does not query the Global Symbol Registry, nor does it poll any private or environment-specific registries. A symbol does not need to be registered or tracked in any table to be identified as valid by Lodash.

How _.isSymbol Actually Validates Symbols

Rather than checking where a symbol is stored, Lodash evaluates the underlying type and internal classification of the value. The implementation uses a two-part validation strategy:

  1. Primitive Evaluation: Lodash first performs a standard type check:

    typeof value == 'symbol'

    This handles any primitive symbol created via Symbol('description'), Symbol.for('key'), or built-in well-known symbols like Symbol.iterator.

  2. Object Wrapper Evaluation: To support edge cases where symbols are boxed inside an object wrapper (such as Object(Symbol('foo'))), Lodash checks if the value is object-like and verifies its internal [[Class]] tag:

    isObjectLike(value) && baseGetTag(value) == '[object Symbol]'

    The baseGetTag helper delegates to Object.prototype.toString.call(value), which returns "[object Symbol]" for symbol wrapper objects.

Why Registry Polling Is Unnecessary

In JavaScript, symbols created natively or via the registry share the identical primitive type symbol. Because the symbol type is an intrinsic JavaScript data type, querying a registry to verify authenticity is redundant and computationally expensive. By checking the primitive type and the internal string tag directly, _.isSymbol achieves an \(O(1)\) validation that functions consistently across all custom, local, and globally registered symbols.