DEV Community

Cover image for Why JavaScript Is Not 'True' OOP
Aivan Carlos Tuquero
Aivan Carlos Tuquero

Posted on

Why JavaScript Is Not 'True' OOP

JavaScript is a language loved by many, but it often gets a bit of a bad rap when it comes to object-oriented programming (OOP). If you’ve come from a background in languages like Java, C++, or C#, you might have heard that JavaScript isn’t a "true" OOP language. But what does that really mean? Let’s unpack this concept and understand why JavaScript stands apart from traditional OOP languages.

1. Prototype-Based Inheritance: The Core Difference

At the heart of the matter is JavaScript’s use of prototype-based inheritance. In traditional OOP languages, you create classes, which are blueprints for objects. These classes can inherit properties and methods from other classes, forming a clear hierarchy.

JavaScript, on the other hand, doesn’t use classes in the same way (at least, not until ES6—and even then, it’s more syntactic sugar, but more on that later). Instead, JavaScript uses prototypes. Every object in JavaScript has a prototype, and objects can inherit directly from other objects. This means there’s no class-to-object translation like in classical OOP languages. Instead, objects beget other objects.

const animal = {
  speak() {
    console.log("Animal speaks");
  }
};


const dog = Object.create(animal);
dog.speak(); // Output: Animal speaks
//Here, dog inherits directly from animal without any class in sight.
Enter fullscreen mode Exit fullscreen mode

2. Encapsulation? More Like Pseudo-Encapsulation
Encapsulation is one of the pillars of OOP. It refers to the bundling of data (attributes) and methods that operate on that data within a single unit or class, with the ability to hide the internal workings from the outside world.

JavaScript’s traditional lack of strict encapsulation is another reason it’s not considered "true" OOP. In the earlier days of JavaScript, there wasn’t an official way to create private variables—everything was public and could be accessed or modified.

With the introduction of ES6, JavaScript added class syntax and, more recently, private fields using a # prefix, which has helped with encapsulation. However, these features are relatively new and are not as robust or enforced as in other OOP languages.

class Animal {
  #name;

  constructor(name) {
    this.#name = name;
  }

  getName() {
    return this.#name;
  }
}

const dog = new Animal("Buddy");
console.log(dog.getName()); // Output: Buddy
console.log(dog.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class

//This private field syntax helps, but the flexibility of JavaScript means it’s still easy to break encapsulation in other ways.
Enter fullscreen mode Exit fullscreen mode

3. Functions Are First-Class Citizens
In JavaScript, functions are first-class citizens. This means you can treat functions like any other object: assign them to variables, pass them as arguments to other functions, and even return them from functions.

While this is a powerful feature, it’s another reason JavaScript doesn’t fit the traditional OOP mold. In many OOP languages, methods are tightly coupled with classes and objects, whereas JavaScript’s functions exist independently and can be used in more dynamic ways.

function sayHello() {
  return function() {
    console.log("Hello!");
  };
}

const greet = sayHello();
greet(); // Output: Hello!
Enter fullscreen mode Exit fullscreen mode

This flexibility is fantastic for functional programming but diverges from the strict method-object coupling seen in classic OOP.

4. Dynamic Typing: A Blessing and a Curse
JavaScript is dynamically typed, meaning variables can hold any type of value and their type can change at runtime. This dynamic nature is at odds with the strict type systems found in most OOP languages, where types are explicitly declared and enforced.

Dynamic typing allows for rapid development and flexibility, but it can also lead to unpredictable behavior and bugs that are hard to track down—something that strict OOP languages attempt to mitigate with their rigid type systems.

let x = "Hello";
x = 42; // No problem in JavaScript!
Enter fullscreen mode Exit fullscreen mode

While dynamic typing is powerful, it’s one more reason why JavaScript doesn’t fit neatly into the OOP paradigm.

5. The class Syntax: Just Syntactic Sugar
In ES6, JavaScript introduced the class keyword, which brought a more familiar syntax to those coming from traditional OOP languages. However, it’s important to understand that this is mostly syntactic sugar. Under the hood, JavaScript is still using its prototype-based inheritance system.

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

  speak() {
    console.log(`${this.name} speaks`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks`);
  }
}

const dog = new Dog("Buddy");
dog.speak(); // Output: Buddy barks
Enter fullscreen mode Exit fullscreen mode

While this looks like class-based inheritance, it’s important to remember that JavaScript is still doing its own thing under the hood with prototypes. This can lead to confusion for developers who expect class-based behavior.

Conclusion: IS JS TRUELY OOP?
So, is JavaScript truly object-oriented? The answer is both yes and no. JavaScript is incredibly flexible and can be used in an object-oriented way, but it doesn’t adhere to the strict rules and paradigms of traditional OOP languages. Instead, JavaScript offers its own unique blend of prototypes, dynamic typing, and functional programming capabilities, making it a powerful and versatile language—just not a "true" OOP one in the classical sense.

Whether you see this as a strength or a limitation largely depends on your background and the kind of programming you’re used to. But one thing is clear: JavaScript’s approach to OOP is unique, and understanding its nuances will make you a better developer.

Top comments (4)

Collapse
 
arsalannury profile image
ArsalanNury

I have never seen somebody implement an application with class-based syntax in pure JS.
I think it is only common with React JS to use class-based syntax.

Anyway, I like JavaScript OOP syntax it's simple and easy to learn :)
Thank you for sharing this article.

Collapse
 
aivantuquero profile image
Aivan Carlos Tuquero

Thanks!

Collapse
 
asmyshlyaev177 profile image
Alex

Nobody really use prototypes for quite some time. Kind of click bait title.

Collapse
 
aivantuquero profile image
Aivan Carlos Tuquero • Edited

I appreciate your perspective. most developers don't write code directly using prototypes anymore. the class syntax has certainly become the standard for creating objects and handling inheritance in modern javascript. however, the underlying mechanics of js are still prototype based, even if we’re not directly interacting with prototypes. The intent of the article was to explain why js isn’t considered "true" oop in the traditional sense, particularly for those coming from languages where classes and classical inheritance are the norm. the title aims to spark discussion and curiosity, but I understand how it might come across as clickbait to some. :)