beginner question on return syntax and use

40 views
Skip to first unread message

Guy Duff

unread,
Jun 25, 2015, 2:09:42 PM6/25/15
to nod...@googlegroups.com
Hi, and thanks for having this forum. I am reading the book entitled beginning node.js by  Basarat Ali Syed.   There is a code example that I am having a little trouble understanding:

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
};
}

// Pattern in use
var awesome1 = printableMessage();
awesome1.printMessage();

var awesome2 = printableMessage();
awesome2.setMessage('A new message for you.');
awesome2.printMessage();
"

I understand everything except the syntax in the return section.  Why is the label the same as function name in each case in the return section.   Why is a return necessary to execute the function at all?  This code was designed to illustrate the concept of "revealing modules"?  I would be very grateful if anyone can elaborate on how this example reveals modules.  Are each of the functions a "module"?  If this is so, am I to assume that the return function is responsible for revealing them?

It seems like the functions are methods of the printableMessage function?  Anyway, sorry for asking such a nube question.  I really want to understand node.js, not just hack into to develop.  - Thanks very much.

Gustavo Machado

unread,
Jun 25, 2015, 5:06:56 PM6/25/15
to nod...@googlegroups.com
Guy,

The function is returning an object, pretty much like { "foo": "bar" }, but it happens to contain the functions the it wants to expose to the caller.

Gus

--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/edcca2f5-4742-419a-a17b-42657c6cd97f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Maximilian Hill

unread,
Jun 25, 2015, 5:07:01 PM6/25/15
to nod...@googlegroups.com
The return is necessary because you use anonymous functions which are
only defined inside the function (printableMessage). The label may
have every name you'll be able to give it.
You can handle (var awesome1 = printableMessage()) like an instance of
printableMessage. The return of them enables you to access its inner
functions.

This not really have to do with node.js only, this is an
JavaScript/ECMAScript thing which you can use on websites too without
any changes, with the only difference that the console.log() isn't
shown on the site but in the console of the developer tools of the
browser.

Ryan Schmidt

unread,
Jun 25, 2015, 5:07:01 PM6/25/15
to nod...@googlegroups.com
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');
Reply all
Reply to author
Forward
0 new messages