I'm looking into how to apply functional programming in javascript, and I'm experimenting with trying to avoid using the class
keyword.
I'm not a fan of going to extreme measures just for the sake of following some paradigm, but I'm curious to see if it's possible to write good code without using classes.
I've had success so far using mainly functions, but there is one situation that I can't really figure out.
When we have behavior that we want to re-use between different objects, we usually (in OOP) create a class that extends another class.
class FlyingThing {
private let _isFlying = false
fly() {
_isFlying = true
return this
}
land() {
_isFlying = false
return this
}
isFlying() {
return _isFlying
}
}
class Duck extends FlyingThing {
quack() {
return 'Quack!'
}
}
const duck = new Duck()
console.log(duck.fly().quack())
Now to the functional approach...
Example taken from: https://medium.com/javascript-scene/functional-mixins-composing-software-ffb66d5e731c
const flying = o => {
let isFlying = false
return Object.assign({}, o, {
fly () {
isFlying = true
return this
},
isFlying: () => isFlying,
land () {
isFlying = false
return this
}
})
}
const quacking = quack => o => Object.assign({}, o, {
quack: () => quack
})
const createDuck = quack => quacking(quack)(flying({}))
const duck = createDuck('Quack!')
console.log(duck.fly().quack())
Ok, I like this idea; we're using composition and we don't have tight coupling between any parents and children. Cool.
However, normally when we use classes, the child has access to the parent's members, and might need to use it in some methods. For example:
class FlyingThing {
private let _isFlying = false
fly() {
_isFlying = true
return this
}
land() {
_isFlying = false
return this
}
isFlying() {
return _isFlying
}
}
class Duck extends FlyingThing {
quack() {
return 'Quack!'
}
// New method - Depends on 'isFlying' defined in parent
layEgg() {
if(isFlying) return
return 'Laying egg...'
}
}
const duck = new Duck()
console.log(duck.fly().quack())
So the question is, how do we solve this elegantly using only functions?
class
keyword. Try to avoid mutable object properties (i.e. make everythingreadonly
, given this looks like Typescript). Then, once you are familiar with immutable objects, you will find patterns that might make alternatives toclass
syntax more appealing. – Necolenecro