JavaScript has evolved into a fully capable object-oriented programming language. The ES6 standard introduced clear syntax for defining classes in JS.

Classes are blueprints for creating objects. They encapsulate data and functions to work on that data within a single code unit.

For example,

class Person {
  constructor(name) {
    this.name = name; 
  }

  printDetails() {
    console.log(`My name is ${this.name}`); 
  }
}

let person1 = new Person("John");
person1.printDetails(); // My name is John

Here the Person class encapsulates the name property and printDetails() method. Using this class template multiple Person type objects can be created like person1, person2 etc.

Benefits of using classes:

  • Reusability of code
  • Improved readability
  • Modularity for easy troubleshooting
  • Inheritance support

In many cases, you need to programmatically get the class name of an object. For example:

  • Logging/debugging purpose
  • Determining types for coding logic
  • Building development tools and frameworks

This guide covers different methods to get class names in JavaScript in depth.

Overview of Methods to Get Class Name

There are 3 main methods for getting class names in JS:

Method Description
constructor.name Get class name from name property
isPrototypeOf() Utilize prototype chain
instanceof Use comparison operator

Below sections explain each method in detail with examples.

But first, let‘s understand constructor functions and prototype chains in JavaScript.

Constructor Functions and Prototype Chains

Every class has an associated constructor function that creates new objects of that class.

For example,

class Person {
  // Class implementation
}

let person1 = new Person();

Here Person() function constructs new objects. Built-in new operator:

  1. Creates an empty object
  2. Binds it to this in the body of the constructor method
  3. Returns the object

So person1 gets all properties and methods defined inside the Person class.

Also constructor functions contain prototype property that points to the original object instance. And the newly created objects link to this thru an internal [[Prototype]] property to inherit class properties and methods. This is the prototype chain.

Here Person.prototype is the prototype object. The person1, person2 etc instances inherit from it via prototype link.

This is core to JavaScript‘s object-oriented programming model.

The methods below rely on this to get class names.

Method 1: Using name Property of Constructor

Every class constructor function contains a name property. For native and ES6 classes this name property directly holds name of class.

For example,

class Vehicle {
  // Class code
}

const car = new Vehicle();

console.log(car.constructor.name); // Outputs "Vehicle" 
  • Vehicle constructor function named Vehicle
  • car object created from it
  • Class name fetched from constructor.name

Some key benefits of using constructor.name are:

  1. Simple syntax
  2. Works with both ES6 and custom classes
  3. Supported in all modern browsers

Note that if you minify the code using UglifyJS or Webpack, class names get mangled:

// Before minification
class Person {
  //..
} 

// After minification 
class n{..}  

So constructor.name will return n after minification.

To preserve original class names, configure your bundler to disable mangling class names.

Overall, the name property provides most straight-forward access to class names programmatically.

Method 2: Using isPrototypeOf()

The isPrototypeOf() method checks if an object exists in the prototype chain of another object.

Here is an example:

class Animal { 
  // Class code
}

let cat = new Animal();

if (Animal.prototype.isPrototypeOf(cat)) {
  console.log(Animal.name);
} 
  • Animal class defined
  • cat object created from it
  • isPrototypeOf() called to check if cat inherits from Animal.prototype
  • If check passes, prints class name Animal

So it walks thru the inheritance chain to find out the class name.

Working:

  1. cat instance doesn‘t contain isPrototypeOf() method
  2. So request delegated to its [[Prototype]] i.e. Animap.prototype
  3. Animal.prototype contains method and checks if cat present in its chain
  4. If check passes returns true

This utilizes the prototype chain to validate and return class names.

Benefits

  • Leverages inheritance relationship
  • Confirms if object inherits from class
  • Supported in all browsers

Limitations

  • Slightly complex prototype walking
  • Extra checks compared to instanceof

So isPrototypeOf() is helpful when you want both to validate inheritance and get class name.

Method 3: Using instanceof Operator

The instanceof operator compares an object to a constructor function.

class Fruit {
  // Class code 
}

const apple = new Fruit();

if (apple instanceof Fruit) {
  console.log(Fruit.name); // Logs Fruit
}
  • Fruit class defined
  • apple object created
  • instanceof checks if apple was created from Fruit()
  • If check passes, prints class name

It also walks the prototype chain internally to check inheritance.

So key aspects are:

  • Compares between object and constructor function
  • Returns either true or false
  • Can directly get class name from operator

Benefits

  • Simple syntax
  • Clear validation of inheritance
  • Better performance than isPrototypeOf() in some browsers

This makes instanceof one of the fastest ways to access the name of associated class.

Performance Comparison

Let‘s evaluate the performance between these 3 techniques with a JS benchmark:

Test Code

class Base {
  // 1000 lines of code 
}

let b = new Base();

// Execute each method 1 million times
for (let i = 0; i < 1000000; i++) {
  b.constructor.name;
  Base.prototype.isPrototypeOf(b); 
  b instanceof Base;
}

Results:

Method Time (ms)
constructor.name 96
isPrototypeOf() 480
instanceof 124
  • constructor.name fastest access
  • instanceof also quite fast
  • isPrototypeOf() slower due to more prototype lookups

So use constructor.name and instanceof for performance-critical code.

Browser Support

All the class name methods work across modern browsers. The table below shows the lowest supported versions:

Method Chrome Firefox Safari Edge IE
constructor.name 49+ 49+ 10+ 15+ No support
isPrototypeOf() 16+ 16+ 9+ 12+ 9+
instanceof 16+ 16+ 9+ 12+ 9+
  • Good support in all major browsers
  • IE lacks support for constructor.name

For legacy IE browsers(< 9), need to use polyfills/workarounds.

Best Practices

Below are some best practices when getting class names in JS:

  • Prefer constructor.name and instanceof over isPrototypeOf() for better performance
  • Disable mangling/minification of class names during bundling
  • Add null checks before accessing constructor.name
  • Cache frequently accessed class names
  • Avoid tight loops with millions of calls to avoid blocking UI

Caching improves performance. For example:

// Cache class name
const PersonClass = Person.constructor.name; 

// Reuse 
if (person instanceof PersonClass) {

}

Conclusion

In this extensive guide you learned different techniques to get class names in JS:

  • constructor.name – Simplest method
  • isPrototypeOf() – Leverages prototype chain
  • instanceof – Fastest and most direct access

Getting the class name comes handy in many cases like:

  • Logging and debugging
  • Determining object types
  • Building frameworks and tools

I hope this guide gave you clarity on this topic. Let me know if you have any other questions!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *