Javascript closure inner function to update outer variables

Playing with the below code :smile:

var getsay = function saynum() {
  // Local variable that ends up within closure
  var num = 666;
  var toy = 99;
   num++;
  var toyer = function() {this.num = this.num + toy; alert("toyed :");}
  var sayAlert = function() {alert("pre:" + num);  num =num + 1000; alert("post:" + num); }
  
  return sayAlert;
}
 var  getsay1 = new getsay();

 alert("first call");
 getsay1();
 alert("2nd call same instance");
  getsay1(); 
 alert("second call new instance");
 var  getsay2 = new getsay();
 getsay2();

etc
will easily show the inner function, have read acess to variable like num ,however it can not update it outside its own scope; while this behavior is appropriate in most situations, can any one suggest a neat way to update the variable in the outer scope so that any new construction of outer function gets the updated values?

use object properties instead of variables. objects are passed by reference, while primitives (strings, numbers, booleans, null, undefined) are passed by value.

Hi, Yes you are right but that is not the issue here; I spent a little more experimenting with what I was meaning to bring in ;And here is the resolution I got for myself : the point is the inner function takes its life[stack] once the outer function is called,carrying all referenced variables from the outer function and after that it behaves on its own with no reference to the outer function variables; hence at the time of execution of the inner function it does not have any reference to the outer function [which would have finished execution anyway} ,hence it can not modify the outer function variables.

Ok… here’s what’s happening. Every time you call getsay(), you’re getting a brand new set of its local variables, including num. Your sayAlert() function is indeed updating the num variable, or at least the instance of that variable that was created with its respective getsay() call.

If you want the same num value to be shared across all “instances”, then you’ll need to declare it outside the getsay function.

var getsay = (function () {
  var num = 666;
  num++;
  
  var getsay = function saynum() {
    // Local variable that ends up within closure
    var toy = 99;
    var toyer = function() {this.num = this.num + toy; alert("toyed :");}
    var sayAlert = function() {alert("pre:" + num);  num =num + 1000; alert("post:" + num); }

    return sayAlert;
  }
  
  return getsay;
}());

var  getsay1 = new getsay();

alert("first call");
getsay1();
alert("2nd call same instance");
getsay1(); 
alert("second call new instance");
var  getsay2 = new getsay();
getsay2();

Well Jeff that was something neat. I like it and I also like to add some additional note about what this solution is doing. I have just renamed some of the functions invoked to bring some analogy with real world , where an empire once created through getEmpire() , gives a senate and no matter how many times you create the senate it return the same politics function , so the senate function is a closure within the getEmpire and the senate function has a closure as a politics which is returned every time a new senate is created without bothering to invoke getEmpire.
Effectively we have a pattern here : there is closure within a closure within the initial getempire() function where the outer closure acts like a singleton factory ,in the javascript sense which returns the same ( inner) closure function however many times it i being created, while itself remaining a closure to the initial scope of getEmpre. Every time a new senate is created its own variables are reset [as shown by the value of toy]. So politics is played within a senate that can be reset or created new and the num variable from empire remain the same one even within any new senate.
Here is the modified code:

var getEmpire = (function () {
  var num = 666;
  num++;
  
  var senate = function saynum() {
    // Local variable that ends up within closure
    var toy = 99;
    var toyer = function() {   alert("toye reset from :" + toy);toy = 99; }
    var politics = function() {alert("pre:" + num);if (toy == 99) { alert ("new senate");} ; num =num + 1000; toy = toy + 1;alert("post:" + num); if (num >2000){ new toyer();}}
    
    return politics;
  }
  
  return senate;
}());

var  senate= new getEmpire();

alert("first call");
senate();
alert("2nd call same instance");
senate(); 
alert("second call new instance");
var  newsenate = new senate();
newsenate();