0

Before I dive into the question I want to clarify that my use case involves patching a trans-compiler to generate a proper equivalent, hence the somewhat awkward question.

I want to shadow an outside variable but initialize it to the same value as outside as well. Here is an example:

var a = 2;
(function(){
    var a = a;
    a += 3;
    // I want `a` to be 5
})();
// I want `a` to be 2

I realize with the above example the internal a will be NaN (undefined + 3), but can I initialize the variable doing the shadowing to the same one that it shadows somehow? Passing it as an argument is not an option as that function will be written by the user, the only thing that will be consistent is the presence of inner scope. I was thinking of changing the name of internal variable a but the compiler isn't currently built in a way to track it easily and this would introduce additional headaches.

Alexander Tsepkov
  • 3,946
  • 3
  • 35
  • 59

2 Answers2

4

You need to pass a as parameter in your IIFE.

(function(parameter){
 // «parameter» contains the given value.
 // parameter = "Some value".
})("Some value");

Something like this:

var a = 2; // Variable declaration in the global scope.
(function(a) {
  a += 3;
  // I want `a` to be 5
  console.log(a); // Prints the current value in the local scope.
})(a); // The parameter: var a = 2;
console.info(a); // Prints the current value in the global scope.
// I want `a` to be 2
0

Since that is a immediately invoked function expression it has a completely different scope than the code written outside of it. There's no way to do what you are asking without passing in an argument in some way (whether directly when executing or using bind), or changing the function so the scope is that of the scope where the wanted var a is defined.

With that being said perhaps you can return some methods that will set a to the appropriate value.

http://jsbin.com/vazequhigo/edit?js,console

var a = 2;
w = (function(){
    var setA = function(val) {
        a = val;
    }
    var addA = function(val) {
        a += val;
        return a;
    }

    var a = 0;

    return {
        setA: setA,
        addA: addA,
    };
})();

w.setA(a);
console.log(w.addA(3));
pizzarob
  • 11,711
  • 6
  • 48
  • 69
  • Function scope can't be changed in anyway. *bind* is used to set *this*, which is an entirely different thing. – RobG Sep 08 '16 at 02:08
  • @RobG after passing in the value of `this` as the first parameter of the `bind` method you may pass in additional arguments into the `bind` method that will prepend to arguments provided to the bound function when invoking the target function. – pizzarob Sep 08 '16 at 15:41
  • Also @RobG the function scope could be changed by changing the way the function is defined. By defining a regular function rather than an IIFE the function would have access to `var a` from the outer scope. – pizzarob Sep 08 '16 at 15:57