Home > other >  If a variable is created within the scope of a function that returns a function that uses that varia
If a variable is created within the scope of a function that returns a function that uses that varia

Time:02-08

function creatPrintNumFunction()
{
  var num= 12;
  return function printNum()
  {
     console.log(num);
  }
}

 var printer = creatPrintNumFunction();
printer.num =13; //this part doesn't work but is there a way to access this Num variable Outside the creatPrintNumFunction, The printer function must be finding the num variable from somewhere.
printer();

So how can I get this code to print 13 instead of 12 most importantly with out changing any of the code of the createPrintNumFunction().

For more context on what I really need to use this theory for. I'm using an external module express-sessions in node.js that I don't want to change. There is this 'store' variable where all the sessions are stored that I need to access only problem is that it's created within a function.There is another way i could access it but it's not really convenient

CodePudding user response:

So, the comment you wrote about printNum() function being able to access the num variable somehow is due to JavaScript closures. Closures are an important JavaScript topic which I would recommend looking at some online resources or this stackoverflow post JavaScript closures to learn about. Essentially when you return the printNum function from createPrintNumFunction, the printNum function will remember the num variable that was declared in createPrintNumFunction. But to answer your question of whether you can access the variable outside of the scope it was declared in, then the answer is no. An outer scope cannot access variables from an inner scope. Inner scopes can access variables from outer scopes. So, unless you are keeping track of the num variable from outside of the scope that it was declared in, you won't be able to access the value num holds outside of the scope it was declared in.

So, here you can change the value of num inside of the printNum function itself like this:

function creatPrintNumFunction() {
  var num = 12;
  return function printNum() {
    num = 13;
    console.log(num);
  };
}

var printer = creatPrintNumFunction();
printer.num = 13; //this part doesn't work but is there a way to access this Num variable Outside the creatPrintNumFunction, The printer function must be finding the num variable from somewhere.
printer();

You could define a global variable that keeps track of the num variable. Then through the scope chain the value used inside of the printNum function for the num variable will resolve to the value your global variable currently contains like so:

var num = 12;

function creatPrintNumFunction() {
  return function printNum() {
    console.log(num);
  };
}

var printer = creatPrintNumFunction();
num = 13; //this part doesn't work but is there a way to access this Num variable Outside the creatPrintNumFunction, The printer function must be finding the num variable from somewhere.
printer();

I'm sure there are other methods to go about this as well but I hope that one of the above methods fits your need.

CodePudding user response:

Looking for something like this?

function creatPrintNumFunction() {
  const f = function printNum() {
    console.log(f.num);
  };
  f.num = 12;           // set .num property to initial value
  return f;             // return function "printNum"
}

var printer = creatPrintNumFunction();
printer.num = 13;
printer();

printer.num = 42;
printer();

CodePudding user response:

There is this 'store' variable where all the sessions are stored that I need to access only problem is that it's created within a function. There is another way i could access it but it's not really convenient

No there is no way to access store without modifying the code. And you shouldn't modify the code of an external module, because store is likely made inaccessible for a reason. Changing the code might result in a code base that would prevent you from updating the express-sessions.

Having the need to do that sounds like an XY-Problem.


If it is your code and you want to allow the variable to be accessed there are different ways to do that. You for sure could move var num outside of creatPrintNumFunction (as described in the answer of alonealgorithm but that breaks the encapsulation you had before. Whether that is a good idea or not depends on the actual use case. But you need to be aware that if you do that that every "print" function returned from creatPrintNumFunction then uses the same variable.

Let's say you don't want to move num out of the scope of creatPrintNumFunction because every "print" function returned from creatPrintNumFunction should have its own num variable.

What then you could do is to create another function (e.g. set) within creatPrintNumFunction that can change num and assign this function as a property to the function you return from creatPrintNumFunction.

function creatPrintNumFunction() {
  var num = 12;
  
  // both "set" and "printNum" create here
  // have a closure over the same "num" variable
  function set(val) {
    num = val;
  }

  function printNum() {
    console.log(num);
  }

  // the "set" function is assigned as a parameter to your
  // printNum function
  printNum.set = set;

  return printNum;
}

var printerA = creatPrintNumFunction();
var printerB = creatPrintNumFunction();
printerA.set(13)
printerB.set(23)
printerA();
printerB();

The advantage of this approach is that you don't expose num and you can control in your set function how/if num can be changed.

  •  Tags:  
  • Related