Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

92
Views
lodash's isElement equivalent in pure JS

Right now I am using isElement by lodash to check if an element is DOM likely. I want to get rid of this library so I am looking for a pure JS implementation of this function.

I'm using this, but I don't know if it's the right implementation and if I'm ignoring any edge cases:

const isDOMElement = el => el instanceof HTMLElement

Update

I have tested (codepen link) the four proposed implementation, in all cases is working as expected, maybe the one proposed by @cesare covers most of the cases, but also the one proposed by @peter-seliger is clever and work with an "outside of the BOX" thinking. Finally, both @David Thomas and the one I firstly use, works for most of the cases.

So in conclusion I think, as David Thomas points It's just a matter of preference.

P.S: The tags used for the test are extracted from MDN's HTML elements reference

P.S2: Not sure on how to proceed and what answer accept. Both cesare and peter have a good point

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

One could give a try to ...

function exposeImplementation(value) {
  return Object
    .prototype
    .toString
    .call(value);
}
function getInternalClassName(value) {
  return (/^\[object\s+(?<className>[^\]]+)\]$/)
    .exec(
      exposeImplementation(value)
    )
    ?.groups
    ?.className;
}
function isHTMLElement(value) {
  return !!value && (/^HTML(?:[A-Z][A-Za-z]+)?Element$/)
    .test(
      String(
        getInternalClassName(value)
      )
    );
}

console.log(
  getInternalClassName(document.createElement('h1')),
  isHTMLElement(document.createElement('h1'))
);
console.log(
  getInternalClassName(document.body),
  isHTMLElement(document.body)
);
console.log(
  getInternalClassName(document),
  isHTMLElement(document)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

about 4 years ago · Juan Pablo Isaza Report

0

Look at the implementation from library source code:

https://github.com/lodash/lodash/blob/master/isElement.js

about 4 years ago · Juan Pablo Isaza Report

0

This is the lodash util:

function isElement(value) {
  return isObjectLike(value) && value.nodeType === 1 && !isPlainObject(value)
}

Basically with isObjectLike it checks that the value passed is a non null object ( since null is an object in js ) and with !isPlainObject that it is not a plain object ( since it could be an object carrying a "nodeType": 1 entry and because an HTMLElement instance has nested protos.

The isPlainObject util is this:

function isPlainObject(value) {
  if (!isObjectLike(value) || getTag(value) != '[object Object]') {
    return false
  }
  if (Object.getPrototypeOf(value) === null) {
    return true
  }
  let proto = value
  while (Object.getPrototypeOf(proto) !== null) {
    proto = Object.getPrototypeOf(proto)
  }
  return Object.getPrototypeOf(value) === proto
}

As you can see the first check is redundant since it checks isObjectLike again, but the main caveat in my opinion is that it doesn't cover other objects case, since for example "Arrays" are objects too hence they pass the check:

const arr = [1, 2]; // array
arr.nodeType = 1; // add nodeType property to the array object
console.log(isElement(arr)); // true Lodash

Try it yourself.

I think it's safer to check if the object has a nodeType property that is inherited:

const _isElement = (node) =>
    typeof node === 'object' &&
    node !== null &&
    !node.hasOwnProperty('nodeType') &&
    node.nodeType &&
    node.nodeType === 1
  

const el = document.createElement('h1'); // node
const arr = [1, 2]; // array
arr.nodeType = 1; // add nodeType property to the array object

console.log(isElement(arr)); // true Lodash
console.log(isElement(el)); // true Lodash

console.log(_isElement(arr)) // false
console.log(_isElement(el)) // true

In any case I prefer using your check which already covers most of those checks since any primitive non object is not instance of HTMLElement, null is not instance of HTMLElement, and an HTMLElement instance has a "nodeType" poperty but it is inherited from proto and not an own property, :

const isDOMElement = el => el instanceof HTMLElement
//or
const isDOMElement = el => el instanceof Node

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!