Home > OS >  How to declare function outside the loop
How to declare function outside the loop

Time:10-11

I am receiving this error warning message, how is it fixed in the code?

Functions declared within loops referencing an outer scoped variable may lead to confusing semantics

I have googled this error message and somewhat understand why it appears but I don't really understand how I can fix it in my particular case.

What would need to be changed or adjusted in the code to remove the warning?

enter image description here

Originally using forEach: https://jsfiddle.net/dvcLbekf/

  function createResetHandler(player) {
    const resetVideos = document.querySelectorAll('.exit');
    resetVideos.forEach(function resetVideoHandler(video) {
      video.addEventListener('click', function resetVideoHandler() {
        player.destroy();
      });
    });
  }

CodePudding user response:

Since the behavior of the event handler is not dependent on the looped-over variable,

function createResetHandler(player) {
  const reset = () => player.destroy();
  const resetVideos = document.querySelectorAll(".exit");
  for (let i = 0; i < resetVideos.length; i  ) {
    resetVideos[i].addEventListener("click", reset);
  }
}

or

function createResetHandler(player) {
  const reset = () => player.destroy();
  const resetVideos = document.querySelectorAll('.exit');
  resetVideos.forEach((video) => video.addEventListener('click', reset));
}

should be enough.

CodePudding user response:

Quick fix:

function createResetHandler(player) {
  const resetVideos = document.querySelectorAll('.exit');
  resetVideos.forEach((video) => {
    video.addEventListener('click',() => {
      player.destroy();
    });
  });
}

Explanation:

It's probably because you are using a function instead of an arrow function (() => {...}).

A function has its own context: if you call this inside resetVideoHandler, this will refer to resetVideoHandler.

Consequently, your linter detects that a function is using an outer scope variable (player).

However, an arrow function has no context: if you call this inside (() => { console.log(this); }), this will refer to createResetHandler.

Drawback: Arrow functions was introduced in ES6. If you deploy strictly an ES6 code, maybe some users with an old browser will not be able to execute your code; IE in our case https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Functions/Arrow_functions#compatibilité_des_navigateurs.

If you want your code available on (almost) all browsers, you will need a transpiler like Babel (used by Webpack), to transpile your ES6 code to ES5.

Edit

If you want to use only function, and create only one function as @Vuk Stanković suggests, that is a good idea, without the warning, you can write this, but it's dirty:

function resetVideoHandlerFn(player) {
    function destroySelf() {
        this.destroy();
    }
    return destroySelf.bind(player);
}
function createResetHandler(player) {
    const resetVideos = document.querySelectorAll('.exit');
    for (let i = 0; i < resetVideos.length; i   ) {
        resetVideos[i].addEventListener(
            'click',
            resetVideoHandlerFn(player)
        );
    }
}
  • Related