Click here to Skip to main content
15,891,184 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi, need a help on this. is this possible ?

https://jsfiddle.net/57jtpssr/[^]

I just wanted to access a & b variable in a() function. is there is any trick or tricky closures or callback or deferred or work around to make it work without making a & b variables are global ?

We can even consider module variable is a function in custom widget when it comes to dojo.

any workaround without making the variables global would be much appreciated :)

Thanks in advance. :)
Posted

The whole idea of "trick" in programming is wrong.

Short answer is: you cannot access a local variable, and it makes no sense because such variables are placed on stack; and the stack frame is removed after the return from a function.

But let's go deeper. Strictly speaking, this is not always exactly so, because you can make some local variable a part of the closure. Please see: https://en.wikipedia.org/wiki/Closure_%28computer_programming%29[^].

Let's consider the following JavaScript:
JavaScript
function getAccessToLocalVariable() {
      var localVariable = 0;
      return function() {
          localVariable++;
          return localVariable;
      }
}

// let's test it:
var incrementor = getAccessToLocalVariable();
alert(incrementor());
alert(incrementor());

If you run the "test it" fragment, you will get the value of localVariable incremented on each call. Of course, you could return an object which gives direct access to the variable, through two functions returned in this object: one for "getter", another one for "setter":
JavaScript
function getAccessToLocalVariable() {
      var localVariable = 1;
      var getter = function() {
          return localVariable;
      }
      var setter = function(value) {
          localVariable = value;        
      }
      return {"getter": getter, "setter": setter};
}

// let's test it:
var accessor = getAccessToLocalVariable();
alert(accessor.getter());
accessor.setter(10);
alert(accessor.getter());

It's much easier to implement than to explain how it works. I hope the article I referenced above can help you to understand it. First of all, throw out the common misconception that JavaScript is a pure interpreter which process statements one by one. No, it does forward lexical analysis and some pre-processing first. So, when the JavaScript engine detects that some function accesses some objects from the outer context, such as getter accessing localVariable, and the object is accessed through some local variable of the outer context, this local variable changes the way it is stored: it joins the closure, which should be understood as a set of objects "with extended lifetime". Roughly speaking, the objects from this set behave exactly as the object of the global context, but the variables used to access them behave like local variables.

The techniques based on closures can be very useful, because they can help you to hide some context intended to serve as implementation detail, with limited and controlled access from outside context. Of course, the second example makes little practical sense; but such technique (called property feature in object-oriented languages) is introduce to implement some side effect in addition to usual read/assign semantics. Of course, there are many other applications of closures.

—SA
 
Share this answer
 
Comments
Afzaal Ahmad Zeeshan 29-Jul-15 14:59pm    
I am not sure how to vote your answer, because it is both correct and somehow not clear whether user should use that pattern, or was that a clear no. Anyways, JavaScript has started to support Object-oriented using which, with a little change we can convert the model of programming to an object oriented. Allowing us to create members, that can be accessed from different functions also.

Please read Solution 3 to see implementation of what I am talking about.
Sergey Alexandrovich Kryukov 29-Jul-15 15:19pm    
First of all, it has nothing to do with OOP. This is really important to understand, and this article can be very helpful: http://davidwalsh.name/javascript-objects-distractions.

And, by the way, it's hard to argue with this famous speech claiming that JavaScript is the world's most misunderstood language:
http://javascript.crockford.com/javascript.html,
https://yow.eventer.com/yow-2013-1080/the-world-s-most-misunderstood-programming-language-by-douglas-crockford-1377.

I referenced these materials in one of two of my JavaScript articles, where, among other things, I tried to debunk some of such illusions and illustrate some more rational techniques trying to get rid of counter-productive preoccupation with OOP:
Tetris on Canvas, JavaScript Calculator.

No, I think that I explicitly stated that such patterns can be very useful. Please read more carefully. I don't know what could be not clear for you, but for many other members, the whole topic could be pretty difficult.

Moreover, I can argue that such patterns can be better than those using the approach more similar to OOP, which would be using the members, "this.SomeMember". Roughly speaking, this approach is not based on the illusions described in the article I referenced and adverse effects of such illusions. But, more importantly, those members have nothing to do with the concept of "local variables". Those members are not local variables, so discussing them would be off-topic.

—SA
Afzaal Ahmad Zeeshan 29-Jul-15 15:32pm    
Thanks for the links that you have provided, I would give them a look and take some more time to learn these languages and how they work, in depth.
Sergey Alexandrovich Kryukov 29-Jul-15 16:07pm    
You are very welcome. I already know you are quite capable of looking in depth. :-)
—SA
Another approach is to return an object from the function like this:

C#
var module = function(){
    
    var a = 10;
    var b = 20;
    
    return {
        a: a   
    }
    
};

function a(){
    console.log("hi");
    console.log(module().a);
}

a();


https://jsfiddle.net/kellyapt1/57jtpssr/2/[^]
 
Share this answer
 
Initially, I was gonna say, No. Just by judging the question by the term "local variable". But no the answer is Yes, but a simple Object-oriented JavaScript hack. Although JavaScript is not based on Object-oriented semantics but it can be casted to one. The problem that you are having is that the scope goes out as soon as the function hits final bracket.

For this sake, I came to remember I was using the same thing back a few months where I learnt OOP in JavaScript. The scenario was same, so, I created a quick fix to your fiddle to convert the pattern to OOP.

In JS-OOP, you create a variable holding a function, and you design their members using this keyword. Like this,

JavaScript
var module = function () {
  this.a = 10;
  this.b = 20;
}


Now, module is similar to the class in C#. You can create a new instance of it, as,

JavaScript
var mod = new module();


Now our context is similar to C# or Java. Call members on it, do what so ever you want to do. :-) Your code is now changed to this,

JavaScript
var module = function(){
    
    // members
    this.a = 10;
    this.b = 20;
    
};

function a(){
    console.log("hi"); // Your console log
    console.log(new module().a); // Logs 10
}

a();

// Output:
// hi
// 10


You can try out your code sample at: https://jsfiddle.net/afzaal_ahmad_zeeshan/57jtpssr/1/[^]

For more on Object-oriented JavaScript, please refer to MDN[^].
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 29-Jul-15 15:22pm    
I am really sorry, but this is a totally misleading and off-topic answer. Your this.a and this.b are not local variables. I know only one way to expose local variables: closures, and I'm pretty sure that there are no any other way. I do understand that the technique you show is useful, so your information is useful, but you should not confuse the inquirer so much. Look, you object "module" is just a constructor used to create some object equivalent to {a:10, b:20}, nothing else.

In a way, your initial "no" was closer to truth that the rest of your answer. The right answer would be "no, unless closures are involved". Everything else would be irrelevant.

—SA
Afzaal Ahmad Zeeshan 29-Jul-15 15:31pm    
Haha, finally I can say I really need to learn more of JavaScript! Anyways, thanks for your reply and the video you shared. I am watching that, and will definitely want to enhance my knowledge base for such languages. :-)

Thanks anyways.
Sergey Alexandrovich Kryukov 29-Jul-15 16:06pm    
That's great.
—SA
No.
Local variables are stack based: which means that they exist for the lifetime of the function only, and when the function exits the memory they occupied is re-cycled for use by the next function. Additionally, they are not in a fixed location in memory each time, because where on the stack they are stored depends on the activity which lead up to the function being called.
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 29-Jul-15 14:47pm    
Sorry, you missed such important feature as closure. Formally, and lexically, the local variables which belong to a closure should also be called "local", but by their lifetime they behave like "static" (there is no such notion in JavaScript, but global-context variables behave like that). So, as the inquirer asked just about "local variable", such variables should be considered as "local", and closure case is applicable to the topic of the question.
—SA
Afzaal Ahmad Zeeshan 29-Jul-15 14:57pm    
OriginalGriff, time to learn some Object-oriented JavaScript too. :-) Read my answer Solution 3 to learn how to convert JavaScript to OOP to access variables (as members) from functions.
Sergey Alexandrovich Kryukov 29-Jul-15 15:29pm    
Too bad 1) it is not really object-oriented, 2) irrelevant to the question. The way to mimic OOP syntax with JavaScript is not real OOP could be useful in some cases, but would rather distract from understanding what JavaScript does. Even if it is rather colloquially called "OOP", it does not give those dramatic OOP benefits as in .NET or C++.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900