Javascript - Access variable

Asked

Viewed 1,423 times

14

Situation

I am deepening my study a Javascript, and I came up with a little doubt.
In closure, encapsulation and variable scope, all show how to use the var and talk about Local and Global scope, however in all the examples I’ve seen we always use variables with different names to media that "go down".

Example

function x() {              // "x" tem acesso a "a"
    var a;
    function y() {          // "y" tem acesso a "a" e "b"
        var b;
        function z() {      // "z" tem acesso a "a", "b", e "c"
            var c;

Doubt

How to access the "parent" variable when it exists at the location?

Example

function x() {              // "x" tem acesso a "a"
    var a;
    function y() {          // "y" tem acesso a "x.a" e "a"
        var a;
        function z() {      // "z" tem acesso a "x.a", "x.y.a", e "a"
            var a;

Testing

When the variable is global (is not recommended) I can do it like this:

var a = 'Global';
function(){
    var a = 'Local';
    console.log(window['a']);
    console.log(a);
}
  • 4

    This access there, seems to be linked with adequacy of resources to several audiences, as system have contrast functionality or be suitable to visually impaired etc. xD In doubt look at the questions linked by this tag.

  • Removed tag @rray.

  • in that answer I explained a little bit about scopes when using the keyword new: http://answall.com/a/85755/13561, may be related

  • Thank you @Sanction I will read as soon as possible.

2 answers

11


In the case of accessing the function variable previously to the declared scope, I would suggest that you do this in the function property, as it would become difficult or impossible to access the previously declared variable.

Instead of doing like this:

function x() {
    var a = 1;

    function z() {
        var a = 2;
    }
}

It could be done like this:

function x() {  
    x.a = 1;
    function z() {
        z.a = 2;
        console.log(x.a); // Imprime '1'
    }
}

Generally, there are some special cases where it is necessary to access a variable with previous scope, to simulate something similar to static variables.

When there is this need, I usually use a self invoking Function, with its declared variables, being accessed by a function in the return.

Example:

var noMultihits = function ()
{
       var timeout = 0;

        return function (time, callback) { 
             // Sempre limpa o timeout anterior
             // A variável é de outro escopo
            clearTimeout(timeout);

            timeout = setTimeout(callback, time)
        }
})();

noMultihits(500, function (){});
noMultihits(500, function (){});
noMultihits(500, function (){}); 
// Só executa o último, pois a variável é do escopo da funçao autoexecutável

The advantage of that is:

  • Do not pollute the global scope.

  • If it does not pollute the overall scope, there is no risk of collision of variable names.

Still using the self invoking functions (self executable functions) it is possible to join the two solutions, to use something I would call an anonymous object.

var ajaxInfinito = (function anonimo()
{
   anonimo.pagina = 1;

    return function () {
       console.log(anonimo.pagina);
       $.ajax({
          url: 'pagina',
          data: {pagina: anonimo.pagina},
          success: function () { 

              anonimo.pagina++
          }
       });
    }
})()



   ajaxInfinito(); // 1
   ajaxInfinito(); // 2
   ajaxInfinito(); // 3
   ajaxInfinito(); // 4
   ajaxInfinito(); // 5

console.log(anonimo); // undefined, só existe no escopo da self-invoking

In that case we shall make important observations:

  • ajaxInfinito will only receive the value of the function that is in the return of expression anonimo.

  • anonimo is not a statement of a function, but an expression. I would call it a named closure. Note that the console.log anonymity will say that the variable does not exist. This is because that name is only valid within the scope of the autoexecutable function.

  • As we are in another scope, the value of anonimo.pagina will always increase with each call, since it is part of the scope of the autoexecutable function whose internal name is anonimo.

Where access to anonimo, the function could be used with.

Behold:

var soma = (function obj(){
     obj.y = 4;
     obj.z = 5;

   return function () {
        var x = 3;

        with(obj) {
             x += y;               
             x += z;
        }

      return x;
   }
})();

 soma(); // 12

Change of context

@Guilhermelautert commented on the use of this. It is not possible to use it directly, since the context of the functions when called is window. Only when they are instantiated this refers to the object itself.

What can be done is to change the context in which the this is used by the function, passing other values. This is done through the method call.

Example:

function nome (pronome) {
    return pronome + ':' + this.a + ' ' + this.b;
}

nome.call({a : 'Wallace', b : 'Souza'}, 'Senhor'); // Senhor: Wallace Souza
nome.call({a : 'Guilherme', b : 'Lautert'}, 'Mister'); // Mister: Guilherme Lautert

The function $.proxy jQuery does something similar, but it is something that already exists natively.

  • 2

    Had not thought of this way of doing, you arrow a property in the function (since "everything" in javascript is object), I think it is the best solution +1

  • 2

    Why did you win -1? Tell us what can be improved!

  • 2

    I also didn’t understand :/ You will see that the person who gave -1 thinks this is gambiarra.

  • 1

    So whoever gave -1 must know how to answer better than me. So let him answer!

  • 1

    You’re damn right it’s not @Guilhermenascimento. I’ve heard of people who have negatively affected me, and yet, we’re practically friends now ;)

  • 1

    There was an error in the last example, now it’s fixed.

  • 1

    Good answer, many thoughts I didn’t have, also never used with. I wonder if there’s a difference between this.a = 1; and x.a = 1; taking into account that albos point to the main object.

  • 2

    @Guilhermelautert, yes, there is a difference. Whereas you are using the function as a function (it’s strange to say that), and not as an object instance. If you use the this, he will be in the context of windows. Unless you use the technique call

  • 1

    You gave me a good idea ...

  • 1

    But this would not be related to the object in question?

  • 1

    @Guilhermelautert, take a test to fix your learning. https://jsfiddle.net/85jf9szf/

  • 2

    Okay, @Guilhermelautert. I added the example in the post, for you to understand better.

  • @Wallacemaxters "+1 -1" = 0 :D

Show 8 more comments

7

When you define a local variable with the same name as a higher scope variable, the local variable overrides access to the larger scope variable.

One way around this would be to associate the variable to the function instance. Example:

function alfa()
{
  alfa.a = "valor em alfa.a";

  function beta() {
    var a = "valor de a local";
    console.log(alfa.a);
  }
  beta();
}

alfa();

But this type of code stinks and it would be recommended to use different names for such purpose.

  • 3

    Good afternoon Clayton, good answer, but basically the same answer as Wallace: http://answall.com/a/95094/3635 - I hope you take this as a constructive criticism. (I didn’t give the -1)

  • 2

    Thanks for the criticism William, I was editing the reply and had to leave. When I returned and finished, there was already another answer.

  • 2

    I don’t think that’s a reason to deny the guy’s answer. If the answer was bad, the other would also have a negative since they are similar, funny not!? + 1

  • 2

    @Renan but had a -1 in the other. I think the reason for -1 was something else :/ You’ll know

  • 1

    It was I who had given the -1 because I thought I had copied the answer, but then I saw that he said something that happens a lot: The guy publishes at the same time and ends up looking like a copy, even if it isn’t. I pulled out

  • 1

    @Wallacemaxters a criterion I use is to verify if the response difference is greater than 20min, so I classify it as a copy, otherwise I consider "typing time - Equal thinking".

  • 1

    Thanks @Guilhermelautert. This helps not to waver more at this point

  • 1

    @Wallacemaxters Dispo = D

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.