0

I'm not very familiar with javascript's grammar, but I want to define a class, but the keyword this not behave as I want. And I want to know the reason, thanks! The javascript code is below:

var GameUI = function(){
        this.ctx = this.ctx || null;
        this.canvas = document.getElementById('canvas');
        this.chessToMove = {x : -1, y :-1};
        this.style = 'stype_1';
        //this.drawBeginX = 4;
        //this.drawBeginY = 17;
        this.boardStyle = {
            stype_1 : {
                beginX : 4,
                beginY : 17,
                intervalX : 35,
                intervalY : 36,
            },
            stype_2 : {
                beginX : 4,
                beginY : 17,
                intervalX : 10,
                intervalY : 10,
            },
        };

        this.init = function(){
            if(this.canvas && this.canvas.getContext('2d')){
                this.ctx = this.canvas.getContext('2d');

                this.loadImgs();
                //set listeners
                this.canvas.addEventListener('click', this.canvasClick, false);

                return true;
            }

            return false;
        };

        this.setStyle= function(style){
            this.style = style;
        };

        this.canvasClick = function(e){
            //

            let x = e.clientX - this.offsetLeft, y = e.clientY - this.offsetTop;
            //alert('Canvas is clicked! X: '  + x + ",Y: " + y);

            //why this is a canvas obj not a GameUI obj
            console.log(/*'in canvasClick: ' + */this);
        };
    };

Html code:

<html>

<head>
<title> js test </title>
<script type="text/javascript" src="game.js"></script>
<script type="text/javascript" src="ui.js"></script>

<style type="text/css">
    .main{
      margin:0 auto;
      width: 80%;
    }
    #canvas{
      border:1px solid black;
    }

 </style>
</head>

<body>

<div class='main'>
<canvas id='canvas' width='800' height='600'> Your browser is not supported for canvas element </canvas>
</div>
<button> new game </button>
</body>

</html>

As you see, I defined a GameUI class which a canvas was in it with a click function named canvasClick.But surprisely, in the click function, keyword this is a canvas object not a GameUI object, I test it by a log.And this confused me!

stackKKK
  • 25
  • 1
  • 7
  • 1
    Look up `this` behavior in JS. It doesn't act the same as it does in every other language. Long story short, `this` depends on what object the function was called on, which can change. – Carcigenicate Feb 02 '17 at 11:34
  • 1
    There are no classes in JS, you've a constructor function. – Teemu Feb 02 '17 at 11:36
  • store the reference of `this` like `var GameUI = function(){ var self = this; ...` and use `self` later – Satpal Feb 02 '17 at 11:37

1 Answers1

0

Event handlers run in the context of the triggering element, unless told to act otherwise.

This can be changed via bind, which tells it to run in some other context.

this.canvas.addEventListener('click', this.canvasClick.bind(this), false);

Now, in your click callback, this will point to the class instance.

Mitya
  • 33,629
  • 9
  • 60
  • 107