0

i've started learning dom recently. I'm planning on making a website which has a few buttons upon click those buttons, the website makes a drum sound(different drum sound for different button).

So, i wanted to experiment with this keyword in js. As far as my knowledge this should return the name of the object.

So, i expect this code to return me button object but instead it returns Window {parent: Window, opener: null, top: Window, length: 0, frames: Window, …}

here is my js file -

var buttons = document.querySelectorAll('.drum')
console.log(buttons)
buttons.forEach(button => button.addEventListener('click', () =>{
    console.log(this)
}
))

But strangely enough the following code gives me the desired object, i.e gives button object like so -

<button class = "a drum">w</button>

here is the code associated with this result -

var num = document.querySelectorAll('.drum').length

for (var i = 0; i < num ; i++){
    document.querySelectorAll('.drum')[i].addEventListener('click', function(){
        console.log(this);
    })
}

As far as i can see, they both are the same code, just different the way the were written. So, please explain why im getting that behaviour.

if anyone is interested, here is the html file -

 <!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>Drum Kit</title>
  <link rel="stylesheet" href="styles.css">
  <link href="https://fonts.googleapis.com/css?family=Arvo" rel="stylesheet">
</head>

<body>

  <h1 id="title">Drum  Kit</h1>
  <div class="set">
    <button class="w drum">w</button>
    <button class="a drum">a</button>
    <button class="s drum">s</button>
    <button class="d drum">d</button>
    <button class="j drum">j</button>
    <button class="k drum">k</button>
    <button class="l drum">l</button>
  </div>


  <script src="./index.js"></script>
</body>

</html>

Any help is appreciated.Thanks.

default-303
  • 159
  • 1
  • 9
  • 2
    The difference is between arrow functions (`() => { }`) and function expressions (`function() {}`). The respective value of `this` is different in both cases. – Sirko Sep 30 '20 at 10:18
  • thanks, can you explain in detail why the first method doesn't work? – default-303 Sep 30 '20 at 10:19
  • @Sirko is right about that, you can read about it in the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – chebaby Sep 30 '20 at 10:22
  • 1
    Arrow functions do not accept bound context. `this` in arrow functions inherit the parent scope's `this`. In that case, it happened to be with `window` object. Normal anon functions take in context. So their context is set to the DOM element successfully. – Mike Sep 30 '20 at 10:23
  • Another source of information could be this question: https://stackoverflow.com/a/34361380/1169798 – Sirko Sep 30 '20 at 10:27

1 Answers1

0

Arrow functions don't have their own this meanwhile functions declared in "classic" way do.

This way, in the first example, the callback inherits this from the outer scope (which happens to be window). This particular topic is also detailly explained at MDN, so, I recommend you to check it out for more info.

Igor Bykov
  • 1,493
  • 3
  • 7
  • 13
  • hey, thanks. i have one doubt tho - if arrow functions do not have their own `this`, they look up for that in global scope. But why do they return `window` they should be returning `undefined` like others right?? – default-303 Sep 30 '20 at 10:55
  • @default-303 I don't think so. Global `this` is `window` try `console.log(this);` in global scope & you'll see that window is logged. – Igor Bykov Sep 30 '20 at 10:59