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>