- Published on
OOP Basics with JS
- Authors
- Name
- Mike Hacker
- @ki5ibd
Understanding the native JS functions map, filter, and reduce can help bridge the gap between functional programming and OOP, while providing a robust toolkit for managing and manipulating data in JavaScript.
Encapsulation
Encapsulation is about bundling the data with the methods that operate on that data. In the context of map
, filter
, and reduce
, arrays encapsulate both the data and the methods that manipulate the data. This allows you to work with arrays in a more abstract and higher-level way.
Example:
const numbers = [1, 2, 3, 4]
const doubled = numbers.map((num) => num * 2) // `map` method is encapsulated within the array
Abstraction
Abstraction involves hiding the complex implementation details and exposing only the necessary parts. map
, filter
, and reduce
abstract the iteration logic, providing a simpler and more declarative interface for common operations on arrays.
Example:
const numbers = [1, 2, 3, 4]
const evenNumbers = numbers.filter((num) => num % 2 === 0) // Abstracts the loop and condition
Polymorphism
Polymorphism allows methods to be used on different types of objects or in different scenarios. While map
, filter
, and reduce
are array-specific, their usage can be seen as a form of polymorphism where the same method (like map
) can perform different transformations based on the provided callback function.
Example:
const numbers = [1, 2, 3, 4]
const strings = ['1', '2', '3', '4']
const doubledNumbers = numbers.map((num) => num * 2)
const parsedStrings = strings.map((str) => parseInt(str, 10)) // Same method, different operations
Higher-Order Functions
While not strictly an OOP concept, higher-order functions are closely related to the idea of objects with methods (behaviors). map
, filter
, and reduce
are higher-order functions because they take other functions (callbacks) as arguments.
Example:
const numbers = [1, 2, 3, 4]
const squared = numbers.map(function (num) {
return num * num
}) // Passing a function to `map`
Reusability and Composition
One of the OOP goals is to create reusable and composable code. map
, filter
, and reduce
facilitate this by allowing you to define small, reusable functions that can be passed to these methods, enabling complex operations through function composition.
Example:
const numbers = [1, 2, 3, 4]
const double = (num) => num * 2
const isEven = (num) => num % 2 === 0
const sum = (acc, num) => acc + num
const result = numbers.map(double).filter(isEven).reduce(sum, 0) // Functions composed together
Method Chaining
Method chaining is a technique where multiple methods are called on the same object in a single statement. This is a pattern commonly seen in OOP and is facilitated by map
, filter
, and reduce
returning new arrays or values, allowing chains of operations.
Example:
const numbers = [1, 2, 3, 4]
const result = numbers
.map((num) => num * 2)
.filter((num) => num % 3 === 0)
.reduce((acc, num) => acc + num, 0) // Chaining methods together
Conclusion
In summary, map
, filter
, and reduce
embody several core OOP principles:
- Encapsulation: Arrays encapsulate data and related operations.
- Abstraction: They abstract the iteration and transformation logic.
- Polymorphism: They can perform different operations based on the provided callbacks.
- Higher-Order Functions: They take functions as arguments, enabling flexible behavior.
- Reusability and Composition: They promote the use of small, reusable functions and function composition.
- Method Chaining: They support method chaining for clean, readable code.