Why JavaScript is an OOP Language (Even Though It Doesn't Have Classes)

marinbenc🐧 on September 18, 2018

You probably know how OOP works. The class Dog inherits from class Animal, which means that if you have a Dog you access methods from Animal. Thi... [Read Full]
markdown guide
 

I think the defining characteristics of object-oriented programming are: encapsulation, polymorphism, and inheritance.

JavaScript does not use classes. It has prototype based inheritance, rather than class based inheritance. (Yes, I know, ES6 has classes. But that's just syntactic sugar for JavaScript's prototype based inheritance. It isn't the class based inheritance as in C++, C#, or Java.)

That does not make JavaScript any less an OOP language. Does make it different (PBP, as describe). Some relationships are easier to express in JavaScript. Some are harder to express.

Regardless of a developers OOP language of choice, the onus is still upon the developer to use the language well to achieve encapsulation (or modularity), to appropriately use polymorphism, and to judiciously apply inheritance (class-based or prototype-based, depending on language).

In my experience, encapsulation is sometimes neglected causing high-coupling of parts, with very poor cohesion or poor modularity -- which makes unit testing arduous if not nigh impossible. Inheritance is often used where instead composition would be a far better choice. Inheritance is sometimes abused to achieve reuse of the parent (or prototype) functionality rather than used as a polymorphism facility by the caller of methods of a family of objects who provide the same interface (the same contract of behavior).

None of those kinds of issues is the fault of the programming language (JS, C++, C#, Java, or whatever)

DISCLOSURE: I programmed in TypeScript for 2 years. I've got some mileage under my belt in the JavaScript space.

 

Javascript (since ES6 I think) also has classes-based OOP. For example :

class Polygon {
  constructor() {
    this.name = "Polygon";
  }
}

var poly1 = new Polygon();

console.log(poly1.name);

I'm guessing that, behind the scenes, it's still PBP.

 
 

JS is object-oriented, yes. But it isn't class-oriented. The fact that there is a prototype chain is usually not very relevant in practice, but when it does make a difference, it's going to bite you in places you never realized that problems could emerge there. In particular modern web frameworks (React, Redux...) have shown how OOP is used in JavaScript, which is: not at all. 99% of the time you work with plain objects (as in: prototype is object, no methods, only public fields). If you receive a JSON string from an Ajax call, what do you do? Json.parse(...) it. Do you perform any DTO transformation? Or even set a prototype? Nah, too much of a hassle, "let's just use the data". To me this is a strong indication that OOP in JavaScript has way too many hassles and quirks.

With ES6, there was the opportunity of a lifetime: the introduction of a "class" keyword. But instead of starting from a clean table and performing a breaking change, classes are being faked while prototype chains are still merrily working in the background, except that there is now even more confusion among developers than before. Yikes.

 

I feel the title of this article should be Javascript for OOP ... JS isn't entirely an OOP or Functional. So it shouldn't be taught as one.

 

I agree, but the same is true for any language. You can write Java using only static functions and immutable objects, and you can write Haskell functions that perform side effects. I admit the title of the article is a little bit clickbaity, but the point of the article is just to shine a light on prototypal inheritance and language classification. :)

 

Yes, I think my biggest issue with this is the clickbait... It got me to read it because I initially thought "JavaScript's main draw is that it is a 'any paradigm' oriented language... let's see why marinbenc thinks it's an oop language", but I was let down because it's really just an analysis of how to use JS in a OO manner.

Many, MANY people make the mistake of calling it an OO language because its base element is an Object, which is understandably confusing. This is a great breakdown of how prototypal inheritance works and how it can be used in place of the traditional Class syntax from other languages/TypeScript/JS syntactic sugar. It would have been nice to see the other two pillars of OO addressed like Eljay-Adobe mentioned.

You could talk about things like using the module pattern for encapsulation(Revealing module specifically is very encapsulated, where you export/return only the public methods to a caller) and directly point to poolymorphism when talking about the animal/dog inheritance chain (The object IS A dog which IS An animal... polymorphic objects have 2 or more 'IS A' relationships. This is in opposition to composed objects which are 'HAS A' relationships like you might see in Functional programming. It's good to mention both paradigms.... because technically you can use both (and procedural too!) in one application in JavaScript, which is why so many people use the language for things other than web-dev.

Functional Programming in Java would be awkward and clumsy, probably with one super class that everything 'is' and just... bad code. Not as familiar with Haskell, but you would probably have to do similar language hacks to get OOP working in it.

In JavaScript, both just work, but the writer needs to understand what they are doing to keep it from becoming a mess if they use booth approaches equally in one application (and maybe... since engineering is a team sport... don't ever do this to your team-members haha), so it's good to contrast the two any time you're talking about how to do one or the other.

DISCLOSURE: Old guy. (Not making fun of Eljay... I just wanted to make an old guy joke at myself :D)

 

That's why I think it was a horrible idea to introduce a 'class' keyword in ES6 - what a misleading "design" decision

 
code of conduct - report abuse