3

I have a variable which I want to use in only one function. I can write my code like this:

var theAnswerToLife = 42

var multiplyIt = function(x) {
  return ++theAnswerToLife * x
}

I have some other functions in that file, which don't use that variable. Therefore, in order to limit access to that variable to only the multiplyIt function, I could wrap it in an IIFE:

var multiplyIt = (function() {
  var theAnswerToLife = 42

  return function(x) {
    return ++theAnswerToLife * x
  }
}())

Now that variable is available only to the inner function. Such encapsulation obviously makes sense when I have more variables, but is it worth it with only one variable? IIFE syntax is quite heavy, and in a more complex code I could end up having like three nested IIFEs.

How to keep balance between encapsulation and code readability? Where's the borderline?


My environment is Node.js, so a variable defined outside any function won't be global, but will be only available in the module scope.

2 Answers2

3

Given a variable which needs to have a scope beyond a single function call, yet be accessible by only one function, I believe it's okay to not introduce a new scope just for that one function as long as you don't make the variable global.

In other words, I'd put this variable at module scope. You should already have some kind of module system which prevents top-level variables from being accessed by other modules unless explicitly exported. That might mean the traditional IIFE module pattern, or common.js modules or some other format, but whatever it is it should be introducing a new non-global scope for each module, so just use that scope when an additional IIFE feels like overkill.

Ixrec
  • 27,711
1

If your goal is to limit variable scoping, you are making the issue more difficult than necessary.

Consider this function that achieves the same goal with a much more limited scope, both for the internal variables and the function complexity:

function doIt(x) {
  var theAnswer = 42;

  return x * 42;
}

It does the same thing yours does, but without the added complexity of a Clojure or IIFE (Immediately Invoked Function Execution). It also does not expose theAnswer to the global variable pool.

Calling it with this code will result in an error on the last line:

var results = document.getElementById("results");
results.innerText = "Function(3): " + doIt(3); 
results.innerText += ", theAnswer: " + theAnswer;
Adam Zuckerman
  • 3,725
  • 1
  • 21
  • 27