1
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<canvas id="cv" style="border:2px solid black;">
<script>
    class Click {

        constructor() {
            let cv = document.getElementById("cv");
            this.cv = cv;
            let x = 3;
            this.x = x;
            this.cv.addEventListener('click', this.f);   //Line A
            this.f();                                    //Line B
        }
        f() {
            console.log(this.x);
        }
    }
    new Click();
</script>

Line B displays the value of 3 to console. But line A displays 'undefined' because the same function is called by an eventListener.

If I remove all the objectoriented stuff e.g. constructor, class and 'this.', then it works. But it has to be objectoriented. Maybe I misused the 'this' keyword.

L. F.
  • 19,445
  • 8
  • 48
  • 82
Karl
  • 63
  • 6

2 Answers2

3

Change your function to an arrow function

this.f = () => { console.log(this.x); };

Arrow functions are always bound to the class they are created in, normal functions are bound to the class they are called in. The this keyword points to the class the function is bound to.

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
2

This is because of the scope. When a click event is called, it will have the current scope which is from the click. To get through this, you will need to edit as below or use an arrow function

this.cv.addEventListener('click', this.f.bind(this));
Nidhin Joseph
  • 9,981
  • 4
  • 26
  • 48