DEV Community

loading...

Discussion on: OOP vs functional programming

Collapse
peerreynders profile image
peerreynders

TL;DNR

While JavaScript is an imperative language (i.e. it isn't a functional programming language) I think it's fair to call it "Function-Oriented".
From that perspective mastering functions and closures is an essential part of developing JavaScript competence.


While "class-based object-orientation" goes back to Simula (1962) and Smalltalk (1972) it largely became mainstream due to languages like Java (1995) and C# (2000). While both Java and C# have gained a number of features that aren't directly related to classes over the years, it is probably accurate to say that their fundamental base unit of composition is a class instance, i.e. an object.

The same isn't true for JavaScript. The base unit of composition is a function and its stateful counterpart the closure. On a fundamental level object literals are simply associative arrays where the keys are limited to Strings and Symbols while the value can be of any type (in modern JavaScript Map fits the use case of an associative array much better). The notion of an "object with methods" emerges when functions are stored as values in a plain object (the prototype chain largely exists to help reuse functions across multiple objects).

While in Java and C# classes and class instances (objects) are atomic units of composition, in JavaScript an object in the object-oriented sense is an aggregate of a plain object and functions as values.

Personally the mental model of an object as an aggregate clarified the role of the function context this immensely. this is a special reference that gives a function access to some "other data". If a function is meant to act as a method (is accessed via an object reference) it needs to use this to refer to the rest of the "object". But this can also be used to pass any other context with call (or apply) and bind can be used to create another function with a "bound" this (an arrow function's this is automatically bound to the scope it's defined in). But a function is also free to ignore this entirely.

In my judgement the introduction of the module first as a pattern and then as a language feature is more important than the adoption of the class syntax sugar. It's possible to create a well structured code base with just modules, functions and plain objects.

In fact during the ES5 years (2009-2015) an alternate model of object-orientation not based on constructor functions or classes but instead based on object factories emerged (OOP with Functions in JavaScript). A factory creates a plain object holding functions that are linked to "object state" not via this but through the shared closure that created the functions. It's an approach well worth being familiar with in order to get better acquainted with closures.

So in JavaScript object-orientation isn't class-based (class is more of a creational convention) and the base unit of composition is the function (and plain objects). Objects compose as well and objects can compose with functions and closures. As a result objects (and more so classes) aren't always the "go-to" building block in JavaScript - functions and closures often play the role that small classes do in mainstream OO languages.

Aside: There are some opinions that Closure components are a more obvious solution than hooks for stateful functional components (Hooks reimagined, Preact Composition API).