Functional Programming vs OOP: A Beginner’s Guide

Author profile photo for CareerFoundry author Nicole Abramowski.

A popular interview topic for web developers is explaining functional programming versus object-oriented programming. Don’t know what we’re talking about, or are you looking for a little refresher? Look no further.

Functional programming (FP) and object-oriented programming (OOP) are two different programming paradigms. That is, a way of thinking about writing software based around certain principles. 

A paradigm is a set of programming habits that constrain you in some way. This might sound negative, but these trade-offs aim to help limit bugs and mistakes.

Functional programming is quite the hot topic in the JavaScript world recently. Many major JavaScript frameworks these days are based around functional programming ideas. Object-oriented programming, as we’ve explained more in this guide, is more traditional.

We’ll cover these core concepts, how OOP and FP relate to JavaScript and more in this article. Feel free to click on a heading to jump directly to that section.

  1. What is functional programming?
  2. What is object-oriented programming?
  3. Functional programming vs OOP: Pros and cons
  4. What type of language is JavaScript?
  5. Final thoughts

1. What is functional programming?

The obvious answer is that functional programming centers around functions. Sounds simple, but what does this actually mean? Essentially, it involves taking inputs and getting outputs. Functional programming has two key concepts. 

  • Pure functions
  • Avoids shared state and mutable data

Pure functions

We mentioned functional programming is focused on building software based around pure functions. Now let’s break that down.

First, a function is a process that takes some input, called arguments, and returns a value. A pure function has additional criteria:

  • Given the same input, always return the same output
  • No side effects

For example, take the function Math.random():


Math.random(); // => 0.6011236482846291
Math.random(); // => 0.8002747611174926
Math.random(); // => 0.5488561222294628

Even though there are no arguments passed into Math.random(), it returns a different output every time. This means the function is not pure.

Here is an example of a pure function:


const multiplyByTwo (number) => number * 2;

multiplyByTwo(5); // => 10
multiplyByTwo(5); // => 10

Every time you run the multiplyByTwo function with the argument of 5, it will return 10. It also does not rely on any external mutable state elsewhere in the application. This makes it a pure function.

Shared state and mutable data

Once your program grows, it starts to involve many different functions and objects. This is where state comes in. State is a way to create more structure around the status of your code.

State keeps track of the status of your entire application, or of an individual object. For example, if a user has changed the language of the web page, we store this in state. Filters in use during online shopping, current page number or page size, can all be stored in the state.

Shared state is any data that exists in a shared scope, i.e. where values or functions are accessed. A function has its own functional scope (what’s in the function). Pure functions don’t use state outside their own scope.

Functional programming avoids shared state. The philosophy behind this is that shared state requires more research. It takes more energy to avoid negative side effects elsewhere in the application. You need to know the history of every shared variable that the function uses when it’s not pure. This is why pure functions avoid shared state and only rely on data within their own scope.

Mutable data is any data that can be changed once it’s created. Like shared state, functional programming avoids mutable data. Mutable data makes it easier to create side effects elsewhere in the application. In short, it means you’re more likely to introduce bugs to your app.

Examples of side effects are: 

  • Modifying any external variable or object property,
  • Logging to the console
  • Setting off any external process
  • Calling any other functions with side effects

Examples of functional programming languages

Some common functional programming languages are Haskell, Clojure, and Erlang.

2. What is object-oriented programming? 

Object-oriented programming focuses on classes and objects, rather than functions and logic. With OOP, both data and its functionality are grouped together. The structure of OOP includes classes, objects, methods, and attributes.

A class is a blueprint that defines the variables and the methods common to all objects of a certain kind. JavaScript classes are particularly different to other languages, so it’s worth familiarizing yourself with how they work.

Objects are specific instances of a class. Say you have a class Dog, for example. The dog class can be used to create an object, goldenRetriever. This object has unique values for the properties defined in the class.

Methods are functions that are defined with the class and are only available to objects of that type.

Attributes are characteristics of the class that differentiate it from other classes. If our class is Dog, for example, these could be things like color, breed, name, and/or favoriteTreat.

One way to think about attributes is as the noun or adjective of a class, while methods are the verb. One can have many entities inheriting from the same class but holding different data.

Key concepts of object-oriented programming:

  • Encapsulation
  • Abstraction
  • Inheritance
  • Polymorphism

Encapsulation

Encapsulation encloses an object’s methods and properties within the object. The benefit of this is to not expose them. An example would be API extraction, i.e. controlling which methods and data you allow others to use. 

This control helps with race conditions. A race condition occurs when two or more threads can access shared data and try to change it at the same time. This can cause bugs by leading to unpredictable results.

Abstraction

Abstraction hides the complex implementation details and only shows the functionality to users.

For example, you may make a class for Person, and the person has a family and a job. Family and Job can be abstracted to different classes.

Each class handles only that functionality. This groups the data with its related functionality. Abstraction makes it easier to handle complexity by splitting it into smaller parts.

Inheritance

Inheritance allows the parent class to pass functionality to the child class using the extends keyword. This helps make the code reusable rather than writing the same code over and over.

With inheritance there is a parent class and a child class. The child class inherits the methods and attributes from the parent class. It can also have its own properties and methods.

A major benefit of inheritance is reusability. Rather than write code from scratch for your goldenRetriever object and your corgi object, they can both inherit from your Dog class.

Polymorphism

Polymorphism is the ability of a variable, function or object to take on different forms.

In OOP, it’s when you can treat an object as a generic version of something. When you access it, the code determines which exact type it is and calls the associated code.

So you could give a class Shape and a method draw(). When calling Shape.draw(), you’ll get the correct behavior for the specific shape.

Polymorphism lets us modularize our system by handling different modules in consistent ways. This makes the code more reusable. We don’t have to write separate functions like drawSquare() and drawCircle().

Examples of OOP languages

Some common OOP programming languages are Java, Python, C++, C#, and Ruby.

Functional programming vs OOP: Pros and cons

Is one paradigm better than the other? Well, like everything…it depends.

Functional programming is better if you have a fixed set of things and you need to add operations to them. Adding functions that perform calculations on existing data types is one example of this.

OOP works well when you have a fixed set of operations on things, and you need to add more things. Here you add new classes that implement existing methods. The existing classes are left to themselves.

Functional programming leads to reliable results without side effects. It returns what you expect, and has an emphasis on efficiency and optimization. FP uses a declarative style. Programs describe their desired results without explicitly listing commands or steps that must be performed. The downside is that it can be harder to read due to the very large number of functions. 

OOP is very understandable and readable. It uses an imperative style, which is like a simple set of instructions. The downside is it can have unpredictable results. You’re more likely to have side effects due to multiple threads accessing a common resource.

For more of a visual display of some of the big differences between too, this infographic will help:

longdesc="Infographic showing the differences between Functional Programming versus Objet-Oriented Programming, dividing them in terms of key concepts of each, programming that use each, and so on."

3. What type of language is JavaScript?

Now that you’ve learned what the FP and OOP paradigms are, you may now be wondering “Which one of these is JavaScript?” It’s a good question!

Essentially, JavaScript is a prototype-based, multi-paradigm scripting language. There are no inherent classes in JavaScript. Rather, objects inherit directly from other objects through a prototype property.

If you’d like to learn more about how this works, I’ve created a beginner’s guide to JavaScript classes.

JavaScript supports object-oriented, imperative, and functional programming styles. The benefit here is you can choose whichever paradigm best fits your use case.

4. Final Thoughts

As you can see from this introductory guide to what they’re all about, it’s obvious that both OOP and FP are big web development topics in themselves. As a developer, it’s good to understand the basics of each, the differences between them and their use cases.

Object-oriented programming versus functional programming is a controversial topic in the developer community. Engineers tend to swear by one or the other. In reality, both have their benefits and trade offs. Whichever side you’re on, there is something to be learned from both paradigms.

If you’d like to read more about the world of web development, have a look at these articles:

What You Should Do Now

  1. Get a hands-on introduction to web development and build your first website from scratch with our free, self-paced web development short course.

  2. Take part in one of our FREE live online web development events with industry experts, and check out recent graduate Tanimara’s successful career-change story.

  3. Become a qualified web developer in just 5-10 months—complete with a job guarantee.

  4. This month, we’re offering a partial scholarship worth up to $1,365 off on all of our career-change programs to the first 100 students who apply 🎉 Book your application call and secure your spot now!

What is CareerFoundry?

CareerFoundry is an online school for people looking to switch to a rewarding career in tech. Select a program, get paired with an expert mentor and tutor, and become a job-ready designer, developer, or analyst from scratch, or your money back.

Learn more about our programs
blog-footer-image