This article How to decide between classes v. closures in Javascript explains from a direct and with examples, the differences between closures
and class
in JS, but I will put here a summary of what I found more interesting to take into account.
closure
and class
has different fundamental behaviors, where the closure supports encapsulation, being encapsulation one of the main concepts of OOP, on the other hand classes in JS do not support it. This difference has to be taken into account for verses prior to ES2019 where it has a proposal to use var and private methods with the use of the #
, as in your example. This feature is implemented in babel
and it’s not all browsers that support this feature. Without this var private feature, nothing would stop me from doing:
class Counter {
val = 0;
increment(step = 1) {
this.val += step;
}
retrieve() {
return this.val;
}
}
const counter = new Counter();
counter.val = 100; // alterar diretamente o valor de val porque não possui encapsulamento.
console.log(counter.retrieve()); // 2
- We can manipulate the private data of the class implementation, making the class implementation more fragile (for versions prior to ES2019).
class
need the new
to create an instance, while closure
just call the function.
- Each instance of the class shares the same prototype, meaning that a change in the prototype will also affect all instances (example below). Meanwhile, all instances created by closure are unique.
class Counter {
val = 0;
increment(step = 1) {
this.val += step;
}
retrieve() {
return this.val;
}
}
const counter = new Counter();
const counter1 = new Counter();
Counter.prototype.retrieve = () => 'Hello there!'
console.log(counter1.retrieve()); // Hello there
console.log(counter.retrieve()); // Hello there
- And finally, classes are more efficient in terms of performance than closure, because the class creates a reference in memory where all the instances created will share from this reference, that is, it stores in memory something in common that will be used by many. Already closures create instances separate from each other, ie, each instance of a closure will create a unique reference in memory, which will obviously consume more system memory.
In short, if there is no need to create multiple instances of an object,
closures
will be a good option. Otherwise, classes
will be more performatic, but should pay attention to the care for versions of ES that do not support encapsulation.
As you said in your question, it is up to each person to decide what to use. At first I came to think that classes were syntactic sugar for closures, but over time, I realized that’s not quite so. I particularly prefer closure because I feel more comfortable with a more functional paradigm in JS, but I don’t ignore which classes have their merit although the implementation in JS is still a little weird. Anyway, I hope I’ve helped your doubt and it’s up to the discussion.
Not generally, but JS has some idiosyncrasies that might bring some advantage, so I’ll wait for some with friendly authority on the subject to answer. In any normal code, of normal people, in normal language, you can always do it in a simpler way. I think gambiarra, but some language may require a.
– Maniero