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?
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)
);
}
}