Global helper functions and exported function - javascript

I wrote a node.js module which have a main function and two helper functions, I exported only main function and my question is: is it okay to keep two helpers like a global functions or I can find a better way?
function myFirstHelper(args) {
// ...
return result;
}
function mySecondHelper(args) {
// ...
return result;
}
module.exports = function main(args) {
// ...
return result;
};

I think you don't need to worry about the scope for other modules.
However I understand what you feel. If you want to keep clean your feeling, you could use the Self invoking function like below.
You know, you could use this pattern in all javascript environment even outside of nodejs.
(function(){
function myFirstHelper(args) {
// ...
return result;
}
function mySecondHelper(args) {
// ...
return result;
}
exports.main = function(args) {
// ...
return result;
};
})();

You could use nested functions:
module.exports = function main(args) {
function myFirstHelper() {
// ...
return result;
}
function mySecondHelper() {
// ...
return result;
}
// ...
return result;
};
... and there would be no need to pass args since it would be accessible to those nested functions. Yet there's no reason to worry about this unless your module is very large.
The visibility/scope of something only tends to be problematic if the visibility/scope is much wider than its applicability.
For example, a variable declared at the top of a massive function might be a tripping point and a source of confusion and maintenance issues if it is declared/defined at the very top but only used by 3 lines of code towards the bottom. In that case, the visibility of the variable is significantly wider than its applicability, and therefore the reader must kind of keep it in account when tracing through the function for a much longer period of time than it is actually used, increasing the intellectual overhead. Of course, massive functions also tend to be a smell, but that's a different matter.
So here you have functions which are visible within the module. If the module is small and consists mostly of code using these functions, then the visibility/scope of these functions is not significantly wider than their applicability/usage within the module.
That said, nested functions are handy even for pure organizational purposes if you haven't encountered them before, and precisely because of how they allow you to avoid polluting an outer scope. So they might be a handy alternative to consider in this kind of case. But don't worry too much about the scope of a function (or anything) which is already pretty narrow.

Related

Create sub functions that can be called by dot notation

Background:
Building on this question about how to expose a library for unit testing with Jest. I would now like to create a class of functions that can be called with dot notation inside of dot notation (this may not even be possible). First a bit of methodology that I'm currently using:
Here's an example of how I've been modifying the JavaScript Math functions:
Math.mean = function(numericArray){
if(Math.isNumericArray(numericArray)){
return math.mean(numericArray);
}
return false;
}
FYI, The lowercase math.mean() call is to the math library: https://mathjs.org/, and isNumericArray is just a validator to make sure what's passed in is a numeric array.
And then I export it like this:
module.exports.mean = exports = Math.mean;
So Jest can see it for my unit tests.
My actual question:
What I want to do is create an upper level "class" called Math.acs, so you'd make the call into it with Math.acs. Then it would have sub-functions (EG: foo() & bar()) so you'd call them like this: Math.acs.foo(data); or Math.acs.bar(data);
I've tried to encapsulate them into an IIFE:
Math.acs = (function(data) {
function foo(data){
console.log('hi mom');
};
function bar(data){
console.log("hi dad");
}
return bar;
})();
Which didn't work (the CLI can't see anything below Math.acs), I've also tried straight functions inside of functions which also didn't work.
I'm not going to die if this isn't possible, but it would make the half dozen or so functions required in the acs module centralized and easier to maintain. If it's not possible, I can write the individual math modules the same way I've shown above.
You need to take a function with properties and return this function.
Math.acs = (function(data) {
function f() {};
f.foo = function (data) { console.log('hi mom'); };
f.bar = function (data) { console.log("hi dad"); };
return f;
})();

Local function declarations should be put before or after "return"

What are the pros and cons?
Is there a consensus or good practice established for this case?
What says linters tools, code conventions and standard guides about that?
function before(){
// declare variables
function x(){
}
// do stuff
return x();
}
function after(){
// declare variables
// do stuff
return y();
// ------------------------
function y(){
}
}
Another exmaple:
var Person = function(name) {
var person = {
name: name,
smile: smile,
talk: talk
};
// here alongside function execution?
function talk() {
}
return person;
// or here, after return statement?
function smile(){
}
};
It is a matter of personal choice and both has got and sweet side.
In the later case it's useful when developer needs to read quickly how functions are invoked at the top of the source file, without the necessity to scroll down and read the details about function implementation.
A style close to the second one is followed when binding member in angular js.
Here is a link for recommended style-guide on how angular js binding members up top
Since functions get hoisted up the scope, there's no real difference, only preference.
return's natural place is at the end, so why not have it there?

wait for an async operation before requiring other modules

In my main.js, I am reading a file asynchronously. Once my file is loaded, I set some objects in GLOBAL namespace and use them in my required modules (using GLOBAL namespace or not is a different story, I am using it anyway).
My required module immediately expects that variable to exist at the time of loading. So how do I make it wait till my file reading is complete in the main.js? Do I simply require module in the callback of readFile? Or there's a better way to do it?
example:
fs.readFile('./file', function (data) {
// do something
GLOBAL.obj = data;
});
require('./module.js');
module.js
obj.someFunction();
Your gut feeling of disliking that solution is understandable. (Your stomach is right). The proper way of cleaning this up (and you should take the time – future-you will thank you for it):
go through every one of your ten modules
for each one go through all the functions it exports
for each function figure out, what globals they actually depend on.
add those as arguments to the function.
if they take a lot of arguments now, consider grouping them into objects, creating useful models.
if a bunch of functions all depend on the same set of variables, you can also consider creating a factory function
create a function that takes the formerly global variables as arguments and wrap all of the module's code into that function.
make that function the single export of your module. It serves as a factory function and creates the context for all the other functions in that module. It should return whatever the module exported before.
Example
// DB used to be a global
module.exports = function(DB) {
function getUser(user, cb) {
DB.get('user', db);
}
return {getUser: getUser};
};
You can then use it like this:
var module = require('module')(DB);
module.getUser(myUser, function(){}};
Yes, just follow the rule #1 of async programming. Stuff that depends on callback happening must be executed in that callback. Since your require depends on the variable set in async, you can only use your require inside it:
fs.readFile('./file', function (data) {
// do something
GLOBAL.obj = data;
require('./module.js');
});

can ajax callback function see variables from parent function?

function validateHistoryId(input) {
$.getJSON('request.php', {"action": "historyExists", "history_id" : input.value},
function(data) {
console.log(input.value);
}
);
}
i use jQuery ajax call from javascript function. I tried the above code and it works, but I don't know will it cause any problems in the future.
I want to know, can ajax callback function see variables of it's parent function? and is it a bad practice to do so?
This is the JavaScript functional way to doing things. It's called closure: functions carry variable pointers from their current scope and from any other parent scope.
So it's not only good practice, but this is the pattern you should normally follow instead of pushing around parameter objects, etc.
Please notice that the "this" reference is special, it is never closured (as opposed to any other references) and thus always point the global object in anonymous functions.
In fact a developer needs some time to fully employ the power of the closure feature - this is a basic example you just written. In more advanced (and not solely async) scenarios closure helps you to create "fire and forget" behavior, or can provide you with "private" variables that are not accessible from client code (useful for library development). Closure also help you isolate your code so that it will not mess with the global scope.
1) Example: how to create protected variables with closures. You are able to acccess two methods that can access "protectedVariable" but you are not able to access it yourself - so the control is guaranteed.
function protectedScope(initData) {
var protectedVariable = initData;
return {
getter: function() { return protectedVariable; }
setter: function(v) { protectedVariable = v; }
}
}
var methods = protectedScope(10);
console.log(methods.getter());
2) isolation: the following code will not garbage the global scope even with "global" function definitions
var API = (function() {
var protectedVariable = 0;
var myNotGlobalFunction() {
return protectedVariable;
}
return myNotGlobalFunction;
})();

Using factory methods as alternative to passing anonymous functions

I was watching a video on node.js and I saw the speaker say, he prefers to do this instead of using anonymous call backs:
var server = Server.createServer(server.createReq(req,res));
I think its nice too that a named function with parameters can be passed instead of an anonymous function with closure.
Question 1: However the implementation of the createReq probably returns an anonymous function, wouldn't it?
How is this better? I can see it being better because unlike the closure at the createServer level, a closure at the createReq level is more contained - it would not store reference to other unnecessary variables (non req,res).
And as the speaker said, I guess this would help visualize realtionships better between the different parts of the code.
Question 2: Are there any other benefits?
A reason why you might want to call a function that returns a function may be that you are starting multiple servers within the same process, and you want them to share the same request handler.
Another thing to keep in mind is that each anonymous function must be allocated on the heap, and thus incurs some garbage collection overhead. By using a named function instead of an anonymous function, you can sometimes reduce this cost.
For example, maybe something like this untested and incomplete example:
var server = Server.createServer(handleRequest);
function handleRequest(req, res) {
new Client(req, res);
}
function Client(req, res) {
this.req = req;
this.res = res;
this.body = "";
req.on("data", function (chunk) {
self.onData(chunk);
});
}
Client.prototype.onData = function (chunk) {
this.body += chunk.toString();
};
This example uses a small anonymous function to bind the data event callbacks back to the specific instance of Client, but all other functions are named.

Categories