This context discusses JavaScript programming paradigms, focusing on object-oriented programming (OOP) and functional programming, and how React Hooks fit into these paradigms.
Abstract
The text begins by explaining the concept of programming paradigms and how JavaScript is a multi-paradigm language, supporting both OOP and functional programming. It then delves into the characteristics of each paradigm, providing examples and comparisons. The author also discusses the benefits and drawbacks of each paradigm, ultimately concluding that JavaScript allows for a mix of both paradigms. The context also introduces React Hooks as a functional programming approach for managing the state of an app.
Opinions
The author suggests that functional programming, especially with React Hooks, creates cleaner, shorter code that may be less reusable in large, enterprise apps.
The author poses a thought experiment, asking whether it's better to write more "reusable" code (OOP) or shorter, readable code (functional programming).
The author argues that shorter code is quicker but may not be better, and that every organization will differ in their preferences.
The author expresses a preference for short, readable code with minimal inheritance, as prototypical inheritance requires research and memorization, while functional programming is explicit and clear.
The author concludes that while there are benefits to each approach, JavaScript lets us mix both paradigms easily in the same code, and that we probably should.
The author suggests that object-oriented programming's big advantage is inheritance from one class to another, which makes code reusable without duplication.
The author suggests that functional programming is by definition declarative, and may require less documentation or less lines of code than an imperative approach.
What Are JavaScript Programming Paradigms?
And where do React Hooks fit in?
What you need to know for a technical interview:
Know what a paradigm is and why JS is multi-paradigm
Be able to explain OOP and prototypal inheritance
Be able to contrast OOP with functional programming
Adapted from this article by Bhumika Rani by Geek for Geeks
What are the two programming paradigms important for JavaScript app developers?
JavaScript is a multi-paradigm language, but what does that mean?
Let’s define what a programming paradigm is first.
Modern programming languages fall into two categories: imperative (also called procedural) and declarative (also called functional).
Object-oriented programming (OOP), procedural programming, and parallel processing are examples of the imperative programming paradigm.
Functional programming, logic programming, and database processing are examples of the declarative programming paradigm.
JavaScript supports both object-oriented programming with prototypal inheritance as well as functional programming.
Java was traditionally an example of pure object-oriented programming, though the 2018 release added functional programming in the form of something that we will discuss called lambdas.
SQL is an example of pure declarative programming, though there are extensions available from vendors that add procedural elements.
Characteristics of declarative (functional) programming
You declare what you want to happen, not how it’s done.
There are no loops or conditional statements (for a set-based language, like SQL, where you think of data in columns instead of in rows).
There are plenty of filters and operations on the data as a whole, but the data is often considered immutable values (not changeable).
Typical example: In SQL, you describe a set and either display it or apply functions to each column such as sum, avg, or count. So you might find birds in a database by pulling up a filtered list of BirdSounds where AnimalType equals to “Bird”; then play the sound for each by referencing the BirdSound.
Characteristics of imperative (procedural / OOP) programming
You specify exactly how to do something, not just the desired outcome.
Variables, pointers, and stored procedures are commonplace, and data is often considered mutable variables (changeable)
Inheritance is commonplace and typically used as an example of reusable, clean code that helps future developers
Typical example: In Java, you create an Animal object with a .sound() function that generates a sound as well as a variable lastMadeASound that holds the timestamp for the last call to .sound(). You’ll probably write a getLastMadeASound() function. Then you create a Bird object that inherits from Animal, and you write an alias .birdCall() that simply returns sound(). Now you can generate the sounds by iterating (looping) over your array of Birds and calling .birdCall() on each one.
Object-oriented programming, frequently abbreviated to OOP, is the idea of having objects as a programmer-provided data structure that can be manipulated with functions. To create the objects, you need to write classes and frequently a constructor function. The keyword class was introduced into JavaScript in ES6 (ECMAScript 2015), previously classes were defined in Javascript by functions.
Prototypes and prototypal inheritance
Prototypal Inheritance — yes, that’s how it’s spelled — means that vanilla Javascript has objects without classes. This type of inheritance is sometimes called prototype delegation, Behavior Delegation Pattern, or OLOO (Objects Linking to Other Objects).
In JavaScript, it creates a link when we create the object. For objects and class inheritance, it does not copy but only links properties and behavior.
Diagramatically, inheritance is flowing up the chain of inheritance because it’s a behavior delegation link, also known as prototype chain.
A little confused? Understandably so! Try this article on the prototypechain.
How JavaScript differs from other programming languages
Other languages have “classical inheritance” where the software creates a copy of the behavior from parent class into the child when we extend that class. After that the parent and child classes become separate entities.
Behaviors and properties are copied when we create an object or instance of a class using a constructor. At that point both are separate entities.
That’s because they are not linked — it’s just a copy from one to the other.
Compare that to Javascript, where the child’s behavior is just a link up to the parent class’s behavior.
Example of how OOP works in JavaScript:
Overview of Functional Programming
Closures
First class functions
Lambdas
What is functional programming?
Functional programming basically means writing code that does something (declares what is done) but isn’t specific about how to do it (imperative).
One of the largest benefits of functional programming for me that it helps separate mutable variablesfrom non-mutable constants.
I like being able to keep straight what I should mess with (variables) and what I should leave alone (constants) in my code. It’s a personal preference.
What are first class functions and lambdas?
Functions are first-class objects in JavaScript, meaning they can be:
stored in an array, variable, or object
passed as one of the arguments to another function
returned from another function
Lambdas make code more succinct
function (x) { returnx * x };
Compared to the traditional function declaration above, a lambda removes the function and return keywords. That makes these expressions succinct.
Lambdas in JavaScript are usually called by “fat-arrow” functions:
var square = x => x * x;
square(7); // 49
Lambda expressions are sometimes known as blocks or closures.
What the heck is a closure?
Whenever you declare a new function and assign it to a variable, you store the function definition, as well as a closure.
The closure contains all the variables that are in scope at the time that the function definition is created. That lexical scope is maintained.
Closures are analogous to a backpack. It’s like functions come with little backpacks, and in that pack are all the variables that were in scope.
Example of how Functional Programming works in JavaScript:
So where do React Hooks fit in?
React Hooks are a functional programming approach for abstracting away complexity from managing the state (i.e. mutable variables) of an app.
Here’s an example of React code with and without using React Hooks:
Everyone has an opinion on which paradigm is better—and here’s mine:
The huge changes in how to write React now that we have React Hooks have completely changed my mind about code reusability.
If the underlying way you write code is going to change massively and unexpectedly (for the better) when your preferred language or framework changes, do we really want to be using old code?
Maybe it’s better to stay on the cutting edge and de-prioritize reusability, which means favoring functional programming.
Shorter Code Is Quicker, But It May Not Be Better Code
As a new programmer coming in, is it better to desperately try to write more of the “great, enterprise-ready, reusable code” (i.e. the OOP code) that may take over a 100 lines to write, let alone test, or is it better to hop on the functional programming bandwagon and write tested code in 20 lines?
Obviously every organization is going to differ, but I’m all for short, readable code with minimal inheritance, as prototypical inheritance requires research and memorization, while functional programming is explicit and clear.
While there are benefits to each approach, JavaScript lets us mix both paradigms easily in the same code, so I think we probably should!
Object oriented programming’s big advantage is inheritance from one class to another, which makes code reusable without duplication. (A good rule of thumb is to limit inheritance when coding JavaScript or CSS to no more than 3 levels so as to maximize re-usability in your application.)
Functional programming is by definition declarative — your code says exactly what you want to happen and may require less documentation or less lines of code than an imperative approach. But, you may have to specify that imperative approach (i.e. how to do what you want, step-by-step) if it isn’t already built-in, which will naturally increase the code base.
I think functional programming (especially with React Hooks) creates cleaner, shorter code that may be less reusable in large, enterprise apps.
Do you agree or disagree? Let me know in the comments below!