In OOP, the open/closed principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"; that is, such an entity can allow its behaviour to be extended without modifying its source code.
How does this work with classes in ES6?
There are no classes in ES6. It is just a syntactic sugar on the top of the same prototype model. Classes and interfaces actually are useless because of brining too much extra abstraction and a "Gorilla-Banana" problem.
There are no connection between SOLID principles (open/closed in current case) and a language or "classes". That why they are principles.
Open/closed principle means that you should structure your architecture and it components in a way so it could be extended without changing the original. It would take years of practice for software engineer to get some skill and a good vision of the future so he or she could be able to write a simple code which could be easily extended.
For now, I can only suggest here to follow the single responsibility principle and write a lot of very, very small and simple functions/methods. If your method has more than 20 lines of code, then you have to change something.
To do so you may use class-interface complexity like in Java or you can simply use a composition over inheritance, which basicly means, combining some fucntionality together and exactly that approach is used in JavaScript.
This is how I am doing it in ES6 without classes and I do not recommend use "class" keyword in JS:
const Button = {
init(element) {
...
},
...
}
const CustomButton = Object.assign({}, Dropdown, {
init(element) {
console.log('Hey, I just extended base Button and can do whatever I want');
// now we want to call a "parent" and set 'this' to CustomButton and not Button
return Dropdown.init(element).call(this);
}
});
I am still able to call a Button.init() in my app without breaking anything and on pages I need a CustomButton I can call a CustomButton instead.
Right now I am refactoring a Dropdown component in BunnyJS to make it easily extendable and allow building other components like autocompletes, custom selects, tag selectors (multiple selects) and other similar widgets on the top of it. Imagine all those complicated UI widgets we use in every app for years and how much KBs they take. Now all those components will require only about a 6kb and you will be able to build a custom search box, for example, very fast now.
If you liked this answer, please star BunnyJS on GitHub and share it.
Peter Scheler
JS enthusiast
First: JS has no OOP. There is OLOO. The
classkeyword brings only syntactic sugar.At the time of this writing, there are limited options for defining methods and properties with the
classkeyword. If you want to have modification save or non-enumerable methods and properties you have to define them after declaring your "class".In example:
class Car { //... } // Add a property Car.prototype.color = 'white' // Add a modification protected property Object.defineProperty(Car.prototype, 'wheels', { configurable: false, // defaut: false enumerable: true, // default: false writable: false, // default: false value: 4 })Same for statics.