In this example, "printableMessage" is a function. setMessage, getMessage, and printMessage are private functions inside the printableMessage function. Normally you wouldn't be able to get access to those functions from outside the printableMessage function, but in this case you can, because printableMessage returns an object whose properties are references to those private functions, thus "revealing" them outside of the printableMessage function.
To break down the return statement that you asked about:
> return {
> setMessage: setMessage,
> getMessage: getMessage,
> printMessage: printMessage
> };
It's returning a new object, as indicated by the curly braces. If it just said "return {};" that would be returning a new empty object. If it said "return {name: 'Ryan', color: 'Blue'};" that would be returning a new object with two keys: the key "name" with the string value "Ryan" and the key "color" with the string value "Blue". But in this case it's returning a new object with three keys -- "setMessage", "getMessage", and "printMessage", and the values of each of the keys are not strings but rather the private functions defined earlier.
I'm not sure if it is necessarily proper to call them "methods", because the word "method" only applies to a class, and printableMessage is not a class, strictly speaking. (You do not instantiate instances of printableMessage with the "new" operator.) But it does have a similar purpose to a class so maybe it's ok to call them methods.
Conceptually, this printableMessage function is what's called a factory. When you call the function, it returns something to you that you can use as an instance of a class (and each time you call it, it makes a new object / a new instance). Usually, factory functions are named to make their purpose clear. For example, it might be more properly named printableMessageFactory.
In node, a module is usually a separate file. So you might have a file printableMessage.js to define the printableMessage module, like this:
function printableMessage() {
var message = 'hello';
function setMessage(newMessage) {
if(!newMessage) throw new Error('cannot set empty message');
message = newMessage;
}
function getMessage() {
return message;
}
function printMessage() {
console.log(message);
}
return {
setMessage: setMessage,
getMessage: getMessage,
printMessage: printMessage
};
}
module.exports = printableMessage;
Then in another file, let's say index.js, you can include that module and use it, like this:
var printableMessage = require('./printableMessage.js');