Reputation: 1368
This is specific to nodejs.
When is it best to use a module or a class or an object literal?
A module would look like this:
//myModule.js
module.exports = {
function func1() {
console.log("func1");
}
function func2() {
console.log("func2");
}
}
//in another js file
const myModule = require('myModule');
myModule.func1();
myModule.func2();
The class would look something like this. We could also do this the javascript prototype way, but doing this here for simplicity.
//myClass.js
class myClass {
func1() {
console.log("Func1");
}
func2() {
console.log("Func2");
}
}
module.exports = myClass;
//in another js file
const myClass = require('myClass');
let newClass = new myClass();
newClass.func1();
newClass.func2();
Finally, we could have an object literal singleton.
//myObj.js
let myObj = {
func1: function() {
console.log("Func1");
},
func2: function() {
console.log("Func2");
}
};
module.exports = myObj;
//in another js file
let myObj = require('myObj');
myObj.func1();
myObj.func2();
The difference between the class and the object literal is that object literal acts as a singleton; whereas class could have multiple instances.
But what about the difference between an object literal and the module example. Are those exactly the same pattern?
Upvotes: 1
Views: 897
Reputation: 371049
But what about the difference between an object literal and the module example. Are those exactly the same pattern?
A class should be used when there's a chance of it being used properly as a class (for example, if you ever want to put or retrieve data on an instance, where that instance also has methods, a class makes perfect sense).
// MyClass.js
class MyClass {
func1() {
console.log("Func1");
}
func2() {
console.log("Func2");
}
setData(data) {
this.data = data;
}
getData() {
return this.data;
}
}
const instance = new MyClass();
instance.setData('foo');
console.log(instance.getData());
But if, as this case appears to be, you only want to collect similar functions together, a class makes the code much more confusing for no real benefit. Readers of the code (which may include yourself, somewhere down the line) will expect a class to be used for something that a plain object can't do.
Your myModule.js
is pretty much identical to your myObj.js
- both are exporting a plain object which has certain properties on it. The only difference is the existence of the intermediate variable myObj
, which isn't used aside from being an intermediate variable.
Defining the object to be exported in a standalone variable before exporting it can help a bit when you want to reliably reference other properties of the exported object:
// a little bit verbose, have to reference `module.exports` every time
// to get to the exported object:
module.exports = {
getSummary() {
// using "this" instead may not be reliable without a `bind`
const { summary } = module.exports.getAllInfo();
return summary;
}
getAllInfo() {
// ...
}
};
// a little bit more DRY:
const obj = {
getSummary() {
const { summary } = obj.getAllInfo();
return summary;
}
getAllInfo() {
// ...
}
};
module.exports = obj;
You also might (or might not) consider defining the object to be exported in a standalone variable to be more readable. You can use whatever you like that suites your use-case.
Upvotes: 1