Explain Codes LogoExplain Codes Logo

How to get a JavaScript object's class?

javascript
function-identities
instanceof-operator
constructor-functions
Anton ShumikhinbyAnton Shumikhin·Sep 19, 2024
TLDR

If you're in a hurry, here is the tl;dr: You can obtain an object's class in JavaScript using the yourObject.constructor.name property or the Object.prototype.toString.call(yourObject) method.

// You created 'obj' from a class like 'MyClass' console.log(obj.constructor.name); // "MyClass", beautiful and clean isn't it? console.log(Object.prototype.toString.call(obj)); // "[object MyClass]", feels more official right?

Both methods are especially useful for custom objects, but be wary that minification can modify constructor names. Use .constructor.name if you prefer readability and Object.prototype.toString for greater robustness.

Potholes in the rosy road

While constructor.name and Object.prototype.toString methods might seem like a walk in the park, beware of the raining clouds in the form of edge cases:

  • Minification tools such as UglifyJS can change function names, leaving your code without an umbrella. Enable --mangle false to keep them dry.
  • Anonymous functions or variables don't leave traces. It's like playing hide-and-seek with your function names.
  • Objects created in different environments like iframes can pretend to be someone else when you use constructor.name.
  • constructor.name returns "undefined" for objects without a prototype, something like impersonating a ghost.

Don't get caught in the rain! Here's how to handle these situations:

  1. Use function identities instead of relying on .name if you're commuting through minification.
  2. Direct constructor comparison works better than checking name, don't always judge a function by its name.
  3. Function.prototype.toString() with regex can extract function names. It might feel like squinting through the fog, but it gets the job done.

Digging into the object skeleton

Get friendly with the prototype chain

The instanceof operator is like a family tree. You can trace an object's lineage and check if it is a prodigal son turned instance of a specific class or constructor.

console.log(obj instanceof MyClass); // true if 'obj' makes 'MyClass' proud

Class-based creation vs the OG constructor functions

JavaScript is a land of opportunities. You can create objects using constructor functions or the hip class syntax from ES6. The cool thing is our methods work on both. But hey, keep it on the DL and watch for browser support if you're going class style.

Dealing with oddballs

Dealing with native types

When dealing with native types like String, Number, or the socially distant Null and Undefined, use a custom getNativeClass function:

function getNativeClass(value) { return Object.prototype.toString.call(value).slice(8, -1); }

This antiseptic method ensures a clear identification rightly suited for a prim and proper JavaScript type.

Inheritance issues

For those working with inheritance, remember to hit the gym and strengthen the constructor references. That way, instance.constructor.name won’t break a sweat producing the accurate class name.

class ParentClass {} class ChildClass extends ParentClass { constructor() { super(); this.constructor = ChildClass; } }

Cross-environment objects

For objects living out of the local context scope (like frames, web workers), using instance.constructor.name can be like expecting a friendly neighbor. Stick with a faithful friend like Object.prototype.toString or instanceof when predicting behaviour.