简体   繁体   中英

Understanding variable scope with regard to anonymous functions in EventListeners

In the example below, it's the green square I'm interested in.

I get that clicking on the red square returns the value of the variable set higher up.

I get that clicking on the blue square returns the parameter's default value.

I get that clicking on the orange square simply returns the event object.

But why does clicking on the green square not pass in the value from the variable set higher up?

Why is the value returned as undefined ?

Is it possible to pass the value from the variable set higher up into the anonymous function in the EventListener method? Or is this simply impossible?

Example:

 const square1 = 'red'; const square2 = 'orange'; const square3 = 'green'; const square4 = 'blue'; document.querySelector('.square.one').addEventListener('click', () => console.log(square1)); document.querySelector('.square.two').addEventListener('click', (square2) => console.log(square2)); document.querySelector('.square.three').addEventListener('click', (e, square3) => console.log(square3)); document.querySelector('.square.four').addEventListener('click', (e, square4 = 'blue') => console.log(square4));
 .square { float: left; width: 100px; height: 100px; margin-right: 12px; line-height: 100px; text-align: center; color: rgb(255, 255, 255); font-family: sans-serif; cursor: pointer; }.square.one { background-color: rgb(255, 0, 0); }.square.two { font-size: 14px; line-height: 40px; background-color: rgb(255, 127, 0); }.square.three { background-color: rgb(0, 127, 0); }.square.four { background-color: rgb(0, 0, 255); }
 <div class="square one">Click Me</div> <div class="square two">Probably don't click me</div> <div class="square three">Click Me</div> <div class="square four">Click Me</div>

You get 'undefined' because the call back function is expecting a 'square3' parameter which you are not passing.

Basically the square3 that you have defined above is not the same defined within the function scope

The call back function is only passing the event object

You can view the function parameter like variables definitions, which values are defined when we call the function

Why is the value returned as undefined ?

Your callback is accepting 2 parameters, e and square3 . The square3 parameter overrides the square3 global variable in the callback scope. Since addEventListener only passes one parameter (the event) to the callback, the second parameter is undefined .

To fix this, just remove it from the parameter list. So, use (e) => //... instead of (e, square3) => //...

 const square1 = 'red'; const square2 = 'orange'; const square3 = 'green'; const square4 = 'blue'; document.querySelector('.square.one').addEventListener('click', () => console.log(square1)); document.querySelector('.square.two').addEventListener('click', (square2) => console.log(square2)); document.querySelector('.square.three').addEventListener('click', (e) => console.log(square3)); document.querySelector('.square.four').addEventListener('click', (e, square4 = 'blue') => console.log(square4));
 .square { float: left; width: 100px; height: 100px; margin-right: 12px; line-height: 100px; text-align: center; color: rgb(255, 255, 255); font-family: sans-serif; cursor: pointer; }.square.one { background-color: rgb(255, 0, 0); }.square.two { font-size: 14px; line-height: 40px; background-color: rgb(255, 127, 0); }.square.three { background-color: rgb(0, 127, 0); }.square.four { background-color: rgb(0, 0, 255); }
 <div class="square one">Click Me</div> <div class="square two">Probably don't click me</div> <div class="square three">Click Me</div> <div class="square four">Click Me</div>

Is it possible to pass the value from the variable set higher up into the anonymous function in the EventListener method? Or is this simply impossible?

It's probably not needed very often, but for the sake of clarity, one might occasionally wish to explicitly include a parameter with a clearly stated value within an anonymous function within an EventListener .

In the course of asking the question and experimenting with various approaches, I've realised that this is possible , but you need to reference the already declared variable via a parameter default value.

eg

document.querySelector('.square.three').addEventListener('click', (e, mySquare3 = square3) => console.log(mySquare3));

Working Example:

 const square1 = 'red'; const square2 = 'orange'; const square3 = 'green'; const square4 = 'blue'; document.querySelector('.square.one').addEventListener('click', () => console.log(square1)); document.querySelector('.square.two').addEventListener('click', (square2) => console.log(square2)); document.querySelector('.square.three').addEventListener('click', (e, mySquare3 = square3) => console.log(mySquare3)); document.querySelector('.square.four').addEventListener('click', (e, square4 = 'blue') => console.log(square4));
 .square { float: left; width: 100px; height: 100px; margin-right: 12px; line-height: 100px; text-align: center; color: rgb(255, 255, 255); font-family: sans-serif; cursor: pointer; }.square.one { background-color: rgb(255, 0, 0); }.square.two { font-size: 14px; line-height: 40px; background-color: rgb(255, 127, 0); opacity: 0.5; pointer-events: none; }.square.three { background-color: rgb(0, 127, 0); }.square.four { background-color: rgb(0, 0, 255); }
 <div class="square one">Click Me</div> <div class="square two">I've been disabled</div> <div class="square three">Click Me</div> <div class="square four">Click Me</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM