Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Polymorphism in JavaScript lets different objects respond to the same operation in their own way. A function can call area() on a circle or rectangle without knowing which concrete shape it received. Classes and method overriding make this pattern explicit, but JavaScript can also use the same behavior across unrelated objects without a shared class.

What polymorphism means in JavaScript

Polymorphism means that different kinds of objects can be used through a shared operation while providing behavior appropriate to each object. The caller asks for the same operation; the object determines what that operation does.

For example, a function might call area() on any shape it receives. A circle calculates its area differently from a rectangle, but the caller does not need to branch on the object’s concrete type. MDN describes methods with the same name but different implementations in different classes as polymorphism: MDN’s object-oriented programming guide.

How class-based polymorphism works

With classes, a base class can define an operation and derived classes can override it with their own implementations. A call to the method then uses the implementation belonging to the instance.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Illustrative example: shapes with different areas

class Shape {
  area() {
    throw new Error("A subclass must implement area()");
  }
}

class Circle extends Shape {
  constructor(radius) {
    super();
    this.radius = radius;
  }

  area() {
    return Math.PI * this.radius ** 2;
  }
}

class Rectangle extends Shape {
  constructor(width, height) {
    super();
    this.width = width;
    this.height = height;
  }

  area() {
    return this.width * this.height;
  }
}

function printArea(shape) {
  console.log(shape.area());
}

printArea(new Circle(2));
printArea(new Rectangle(3, 4));

This illustrative example uses one method name, area(), with an implementation for each shape. extends establishes the class relationship; each derived class overrides the inherited method. The printArea function calls the shared operation without checking whether its argument is a circle or rectangle. JavaScript class syntax supports inheritance and overrides, and super can be used when a derived method needs to call parent behavior. See MDN’s guide to using classes.

Can JavaScript have polymorphism without classes?

Yes. JavaScript code can accept objects based on the behavior it needs, even when those objects do not inherit from the same class. In this example, the caller expects only that its argument has a callable render() method:

const article = {
  render() {
    return "Rendering an article";
  }
};

const chart = {
  render() {
    return "Rendering a chart";
  }
};

function show(item) {
  console.log(item.render());
}

show(article);
show(chart);

The two objects are unrelated, but show can use either because both provide the operation it calls. This is behavior-based use of objects: the caller relies on a capability, not a declared shared parent. JavaScript does not enforce a declared interface in this example, so an object without a callable render() will fail when show tries to use it.

Classes and behavior-based objects compared

Question Class-based subtype approach Behavior-based approach
Do objects share an explicit inheritance relationship? Yes. Derived classes can extend a common base class. No. Objects can be unrelated as long as they supply the operation the caller uses.
How is the expected operation communicated? The base class can make the shared method visible in the hierarchy. The caller’s use of the method communicates the expected behavior; JavaScript does not declare or enforce an interface in the example above.
Where can shared implementation live? A parent class can provide behavior inherited by derived classes, which may override it. Each object can provide its own implementation; use a shared parent only if the domain and shared behavior call for one.
When might the structure help or hinder? A hierarchy can make a genuine “is a kind of” relationship clear, but an unnecessary hierarchy can add indirection. Independent objects avoid requiring a common parent, but maintainers need to understand which operations callers expect.

These are organizational choices, not a universal performance ranking. Choose the structure that makes the domain and caller’s expectations clearest.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why prototypes matter, even when you use classes

JavaScript’s inheritance model is based on objects and prototype links. When code reads a property, JavaScript looks on the object first and then follows its prototype chain until it finds the property or reaches the end. An inherited method is a property found through that lookup; an object can supply its own property to shadow an inherited one.

Class syntax gives developers a familiar way to express constructors, inheritance, and method overrides, but it operates over this prototype-based model rather than replacing it. MDN explains the mechanics in its guides to inheritance and the prototype chain and JavaScript classes.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When polymorphism is useful—and what to watch for

  • Use one caller for several implementations. A shared operation such as area() or render() can keep caller code focused on what it needs to do, rather than on the concrete object type.
  • Use a class hierarchy when the relationship is meaningful. A parent class can communicate shared behavior and support derived classes that specialize it.
  • Use behavior-based objects when a shared parent is unnecessary. Independent objects can support the same operation without being forced into one hierarchy.
  • Make expectations clear. With behavior-based objects, document or otherwise check the operation the caller needs; JavaScript does not enforce the example’s implicit interface.
  • Avoid confusing a shared method name with identical behavior. The point is that implementations can differ while callers use a common operation—not that all objects must produce the same result.

For the language mechanics behind class, extends, and the prototype model, see MDN’s JavaScript class reference.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.