Home > OS >  Javascript Scope in variables and functions
Javascript Scope in variables and functions

Time:11-05

I was given this snippet to debug in one of my interviews.

var module = (function sumModule(){
  
  var a = 0;
  var b = 0;
  
  const init = (a,b) =>{
    a = a;
    b = b;
  }
  
  function sum() {
    return a b;
  }
  
  return {
  sum: sum,
  init
  }
  
})();

module.init(1,2);
console.log(module.sum())
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

The value being returned is 0 (0 0), the assignment of a and b in func init didn't overwrite the global var a and var b. Why is this so, can someone please explain?

NOTE: I was told to fix it without renaming the function parameters (a,b).

CodePudding user response:

Instead of renaming the parameters you can also refer to the global variables via their namespace like you do with the init function.

*Or just rename the global variables, if that is allowed

var module = (function sumModule(){
  var a = 0;
  var b = 0;
  
  const init = (a, b) => {
    module.a = a;
    module.b = b;
  }
  
  function sum() {
    return module.a   module.b;
  }
  
  return {
    sum: sum,
    init,
  }
  
})();

module.init(1, 2);
console.log(module.sum())
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Because a and b in the assignments of init() function refers to its parameters, not the outer a and b. So those assignments don't affect values of the outer a and b.

CodePudding user response:

Modified answer from @reyno. His example just monkey patch a & b to the module object after the .init call. Therefore this variables are public and not private anymore.

With this you get the same result, but maintain the variables a & b private.

To achieve this, use a private namespace object, like i did with private.

var module = (function sumModule(){

  var private = {
    a: 0,
    b: 0
  }
  
  const init = (a, b) => {
    private.a = a;
    private.b = b;
  }
  
  function sum() {
    return private.a   private.b;
  }
  
  return {
    sum: sum,
    init,
  }
  
})();

console.log(module) // no a or b property
module.init(1, 2);
console.log(module.sum())
console.log(module)  // still no a or b property
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related