According to the Node.js manual:
If you want the root of your module's export to be a function (such as a constructor) or if you want to export a complete object in one assignment instead of building it one property at a time, assign it to module.exports instead of exports.
The example given is:
// file: square.js
module.exports = function(width) {
return {
area: function() {
return width * width;
}
};
}
and used like this:
var square = require('./square.js');
var mySquare = square(2);
console.log('The area of my square is ' + mySquare.area());
My question: why does the example not use square as an object? Is the following valid and does it make the example more "object oriented"?
var Square = require('./square.js');
var mySquare = new Square(2);
console.log('The area of my square is ' + mySquare.area());
The example code is:
in main
using the following may works
This question doesn't really have anything to do with how
require()
works. Basically, whatever you setmodule.exports
to in your module will be returned from therequire()
call for it.This would be equivalent to:
There is no need for the
new
keyword when callingsquare
. You aren't returning the function instance itself fromsquare
, you are returning a new object at the end. Therefore, you can simply call this function directly.For more intricate arguments around
new
, check this out: Is JavaScript's "new" keyword considered harmful?CommonJS modules allow two ways to define exported properties. In either case you are returning an Object/Function. Because functions are first class citizens in JavaScript they to can act just like Objects (technically they are Objects). That said your question about using the
new
keywords has a simple answer: Yes. I'll illustrate...Module exports
You can either use the
exports
variable provided to attach properties to it. Once required in another module those assign properties become available. Or you can assign an object to the module.exports property. In either case what is returned byrequire()
is a reference to the value ofmodule.exports
.A pseudo-code example of how a module is defined:
In the example above
module.exports
andexports
are the same object. The cool part is that you don't see any of that in your CommonJS modules as the whole system takes care of that for you all you need to know is there is a module object with an exports property and an exports variable that points to the same thing the module.exports does.Require with constructors
Since you can attach a function directly to
module.exports
you can essentially return a function and like any function it could be managed as a constructor (That's in italics since the only difference between a function and a constructor in JavaScript is how you intend to use it. Technically there is no difference.)So the following is perfectly good code and I personally encourage it:
Require for non-constructors
Same thing goes for non-constructor like functions:
In my opinion, some of the node.js examples are quite contrived.
You might expect to see something more like this in the real world
Usage
For the ES6 people
Using it in ES6
When using a class, you must use the
new
keyword to instatiate it. Everything else stays the same.At the end, Node is about Javascript. JS has several way to accomplished something, is the same thing to get an "constructor", the important thing is to return a function.
This way actually you are creating a new function, as we created using JS on Web Browser environment for example.
Personally i prefer the prototype approach, as Sukima suggested on this post: Node.js - use of module.exports as a constructor