0

for example i have this program calling functions some with set time outs, some function work just calling them (setTimeout(this.siguienteNivel, 1500); but others needed (the last ones of the code) an arrow function, (​setTimeout(() =>​this.iluminarSecuenciaFinal();}, 1000 * i);) if the arrow function is missing the function does not trigger in these specific cases, i dont understand why this differentiator, the program is in a class, i dont know if that makes a difference

this is a piece, the complete code is this if needed: https://github.com/moorooba/simon/blob/master/index.html

>  elegirColor(ev) {
          const nombreColor = ev.target.dataset.color;
          const numeroColor = this.transformarColorANumero(nombreColor);
          this.iluminarColor(nombreColor);
          if (numeroColor === this.secuencia[this.subnivel]) {
            this.subnivel++;
            if (this.subnivel === this.nivel) {
              this.nivel++;
              this.eliminarEventosClick();
              if (this.nivel === ULTIMO_NIVEL + 1) {
                this.ganador();
              } else {
                setTimeout(this.siguienteNivel, 1500);
              }
            }
          } else {
            this.perdio();
          }
        }

        // ganoElJuego() {
        //   swal("Platzi", "Felicitaciones, ganaste el juego!", "success").then(
        //     this.inicializar
        //   );
        // }

        // perdioElJuego() {
        //   swal("Platzi", "Lo lamentamos, perdiste :(", "error").then(() => {
        //     this.eliminarEventosClick();
        //     this.inicializar();
        //   });
        // }

        perdio() {
          loser.classList.remove("hide");
          setTimeout(this.startos, 1000);
          this.eliminarEventosClick();
        }

        startos() {
          loser.classList.add("hide");
          boton.classList.remove("hide");
        }

        ganador() {
          console.log("diparo");
          this.eliminarEventosClick();
          for (let i = 0; i < 4; i++) {
            // setTimeout(this.iluminarSecuenciaFinal, 1000 * i);
            setTimeout(() => {
              this.iluminarSecuenciaFinal();
            }, 1000 * i);
          }
          // setTimeout(this.ganoJuego, 4000);
          setTimeout(() => {
            this.ganoJuego();
          }, 4000);
        }

        ganoJuego() {
          console.log("ganojuego");
          winner.classList.remove("hide");

          // setTimeout(this.restart, 1500);

          setTimeout(() => {
            this.restart();
          }, 1500);
        }
moorooba
  • 37
  • 4
  • You need to show how `this.siguienteNivel` is defined. – Barmar Jul 02 '21 at 23:30
  • And ideally, please turn this into a [mcve], which should be entirely doable. The only appecriable thing that arrow functions vs. global functions (e.g. event handlers and timeouts) effect is preserving `this`: arrow functions will use `this` _at declaration time_ whereas regular functions use `this` as it exists _at execution time_ (in the case of timeouts, `this` would be [globalThis](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis), which in the browser equates to `window`) And that might even be enough of a hint for you to determine the problem. – Mike 'Pomax' Kamermans Jul 02 '21 at 23:35
  • Does this answer your question? [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Raymond Chen Jul 02 '21 at 23:41

1 Answers1

1

You have to understand how this works in JavaScript:

class Foo {
  bar = 'bar';
 
  log() {
    console.log(this.bar);
  }
  
  method() {
    setTimeout(this.log);
    setTimeout(() => this.log());
  }
}

const obj = new Foo;

obj.method();

In this example, (which represents the relevant part of your code) the method function tries to call log in two different ways.

In the first one, it passes a reference to this.log as a parameter of setTimeout. The setTimeout function receives a function as a parameter and it has no idea of the context in which it has been declared, it's as if you extracted it from the class. In that case this is being evaluated when the function executes and it evaluates to window. The result is undefined because window.bar is undefined.

In the second one, it passes an arrow function whose particularity is to retain this when it is declared. When it executes, this refers to the instance of the class so the result is the same as if you called obj.log(). The result is 'bar' in that case.

Guerric P
  • 30,447
  • 6
  • 48
  • 86