Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

148
Visualizações
Closure in event handler

var element = document.getElementById('test-button');

//event handler
element.onclick = (function outer() {

  var counter = 0;

  return function inner() {

    counter++;
    alert('Number of clicks: ' + counter);
  };
})();
<button id="test-button">Test</button>

I don't understand why the variable counter won't reset to 0 every time the button is clicked, or maybe when it's clicked, only the function inner() get executed, then why the variable counter get set to 0 when first click occurs. The code is from this link, after carefully read their explanation, I'm still confused.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

why the variable counter get set to 0 when first click occurs.

That is not the moment it gets set to 0. This happens when the assignment to .onclick happens. At that moment outer is defined and executed. So that is the moment counter is set to 0. No click is handled yet.

only the function inner() get executed

Indeed. outer is only executed once, when the main script is executed on page load, and then never again. inner is the function that gets assigned to onclick and thus has the role of event handler. inner has access to the counter that is defined in outer, but outer is never executed again.

outer is a so-called immediately executing function.

As a comparison: you could achieve something similar with this code:

var counter = 0;
element.onclick = function inner() {
    counter++;
    alert('Number of clicks: ' + counter);
};

...but the downside now is that counter is a global variable, that could be altered by some other code. To make sure counter is only available to the click handler, a closure is created for it, which you could also do like this:

function outer() {
    var counter = 0;
    element.onclick = function inner() {
        counter++;
        alert('Number of clicks: ' + counter);
    };
}
outer();

The downside here is that outer has a so-called side-effect: it assigns to element.onclick. This is the reason to choose to return inner and leave it to the caller of outer to do something with it, e.g. assign it to .onclick.

Then we get something like this:

function outer() {
    var counter = 0;

    return function inner() {
        counter++;
        alert('Number of clicks: ' + counter);
    };
}

element.onclick = outer();

This is essentially the same as your code: the function is first defined, and then immediately executed. The function that gets assigned to onclick is the one that is returned by outer, i.e. inner.

Yet another way to achieve this encapsulation of counter:

function inner() {
    this.counter++;
    alert('Number of clicks: ' + this.counter);
}

element.onclick = inner.bind({ counter: 0 });

Here the we provide an unnamed object that is always passed as this-argument to inner whenever it is called. As we don't retain a reference to that object outside of this construct, we achieve the same principle: the counter's state is maintained, but is not accessible outside the handler.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda