Avoiding conflicts between variables in Javascript

Asked

Viewed 236 times

0

All modal windows of my system open via ajax and these have their own JS codes with variables and functions. In order to avoid problems with the variables and functions of the screens that call these modals, I thought to adopt the following strategy in the modal JS:

HTML

<button id="btn">
Valor
</button>
<button id="btnSetar">
Setar
</button>

JS

var nome_da_tela = {
    init: function(){
        this.varUm = null;
        var thisLocal = this; 

        $("#btn").click(function(){
           alert(thisLocal.varUm);
        });

        $("#btnSetar").click(function(){
          thisLocal.SetarValor();
        });
    },
    SetarValor:function(){
        var thisLocal = this
        $.get('/echo/json/',{},function(data){
            thisLocal.varUm = data
        });
    }
}

$(document).ready(function(){
    nome_da_tela.init();
});

Follows link for testing. Have you ever had to do something like this? Do you have a better idea? I didn’t like having to create a variable (thisLocal) just to refer to the object outside its scope.

2 answers

1

Have a reference of this to be used in another scope where there is another this does not generate conflicts. It is never necessary for the browser to make a reference to this call another this. this, is also a reference to an object.

Have you ever had to do something like this? Have a better idea?

Already, when I tried to make map editors for a game. It would be better to do nome_da_tela as an instance of an interface. At least it would help to store less information in the browser memory.

var tela = function() {
    // se não foi declarado 'new', retorna uma nova tela
    if (!(this instanceof tela)) return new tela;
};

tela.prototype = {

    init: function() {
        this.varUm = null; // se não fosse null, seria undefined
    },


    setarValor: function() {
        // this se refere à instância
        var me = this;
    }
};

var nome_da_tela = new tela;

Another alternative that does not serve much: create a reference to the object that will be declared in nome_da_tela using a scope (anonymous).

var nome_da_tela = (function() {
    var me = {};
    return me;
})();
  • In this case I would have an interface for each screen? Using two variables, one with the name of the interface and the other instantiated?

  • 1

    Not much use? Module Pattern/Factory Functions in JS (considering only ES5) is a safer option than working with Function Constructor, that usually staff forget they need to use the operator new to instantiate and use the function, just because of this it is necessary to pollute the code with a defensive programming, which is done in the first line of Function tela. Each technique has its advantage, but don’t go around stating that it "doesn’t serve much", and most of the benefits go alongside factory functions.

  • @Gabrielkatakura I agree, but that won’t change the future of the code if it’s protected. This says because it is common to create classes, despite having several advantages for performance.

  • @Onaiggac You can build the interface whenever you want and assign in any Javascript value. Look at an example: alert(new tela().varUm); // vai ser undefined porque tela().init não foi executado

1


In order not to cause conflicts of superscript of globals variables (which I do not recommend using many, usually only use some to be access points), you can encapsulate the behavior of JS of their modals in a IIFE (Immediately-Invoked Function Expression). As in the JS the reserved word var apply scope by function by performing hoisting, if you use the IIFE and the Module Pattern to expose a module you can ensure that variables declared within the IIFE will not have conflicts with external variables. Consider the example:

// tela principal
// {

var show = function() {
  console.log('show - global');
};

var hide = function() {
  console.log('hide - global');
};

show();
hide();

// }

// tela modal
// {


(function() {
  var show = function() {
    console.log('show - modal');
  };

  // variável local, não sobreescreveu a global
  show();

  // variável global, visto que não foi criada uma interna
  hide();
}()); // IIFE

show(); // não foi sobreescrito
hide();

// }

I still recommend that all variables being used within the IIFE are passed by dependency, to make explicit this external dependency and so that any superscripts do not affect the external code.

var hide = function() {
  console.log('hide - global');
};

(function() {
  // se não usar `var`, sobrescreve a variável global
  hide = function() {
    console.log('hide - local');
  };
})();

hide();

var hide = function() {
  console.log('hide - global');
};

(function(hide) {
  // como `hide` foi injetado na `IIFE` e agora é um parâmetro,
  // ela se torna uma variável local, então a sobrescrita
  // não afeta a global
  hide = function() {
    console.log('hide - local');
  };
})(hide);

hide();

  • Since the IIFE is self-executable, you would advise putting in it the $(Document). ready ? And how would I call the Hide (site) out of it?

  • I advise you that the $(document).ready stay inside the IIFE, for the IIFE is immediate, while the ready is an event record that awaits the document be loaded.

  • All your code should be inside the IIFE, soon hide would be accessible to everyone there.

  • 1

    The good thing is that in this way all my code looks exactly the same, with the difference of being inside the (Function(){ code })();

Browser other questions tagged

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