Lodash isElement with Shadow DOM Nodes
Lodash provides the _.isElement utility to determine
whether a given value is likely a DOM element. When working with the
Shadow DOM, developers often wonder how encapsulated nodes and shadow
roots are evaluated. This article outlines the specific node properties
required by _.isElement, explains how it evaluates elements
inside a shadow tree, and clarifies why a ShadowRoot
instance itself is treated differently.
Core Properties Checked by _.isElement
Under the hood, Lodash's _.isElement implementation
relies on three strict criteria:
nodeType === 1: The propertynodeTypemust be strictly equal to the number1, representing anElement(Node.ELEMENT_NODE).- Object Type (
isObjectLike): The value must be a non-null object (typeof value === 'object' && value !== null). - Prototype Identity (
!isPlainObject): The object must not be a plain JavaScript object literal. It must inherit from a prototype chain typical of DOM nodes (such asElement.prototypeorNode.prototype) rather thanObject.prototype.
Shadow DOM Elements vs. ShadowRoot
When dealing with modern Web Components and the Shadow DOM, distinction must be made between elements within the shadow tree and the shadow root itself:
Elements Inside a Shadow Tree
Any standard HTML or custom element appended inside a shadow tree meets all mandated properties:
- It has a
nodeTypeof1. - It inherits from
HTMLElementorElement. - It passes
_.isElement(node)and returnstrue.
The ShadowRoot Node
A ShadowRoot boundary itself is not an
Element; it is a document fragment.
- A
ShadowRoothas anodeTypeof11(Node.DOCUMENT_FRAGMENT_NODE). - Because
_.isElementrequiresnodeType === 1, passing aShadowRootinstance to_.isElement(shadowRoot)returnsfalse.
Summary Checklist for Node Compatibility
To ensure any node—whether native, slotted, or mocked in a test
environment involving the Shadow DOM—is recognized by
_.isElement, it must satisfy:
value != nulltypeof value === 'object'value.nodeType === 1Object.prototype.toString.call(value) !== '[object Object]'(or an equivalent prototype check ensuring it is not a plain dictionary)