0

I have a class prototype called "viewport", goes like this (its really long so just snippets)

function Viewport(Container) {
    this.x = 0;
    this.y = 0;
    this.w = 0;
    this.h = 0; 
...

Then at some point I have this

    this.Draw = function() {
        this.Canvas.width = this.w;
        this.Canvas.height = this.h;
        cDrawGrid(this.ctx, this.x, this.y, this.w, this.h, this.scale);
        //add other draw calls later
    }

And even further down the line I got this

    this.onMouseMove = function(e) {
        if (!this.bMoving) return;
        e = getEvent(e);
        this.x += e.clientX - this.LastMouseX;
        this.y += e.clientY - this.LastMouseY;
        this.LastMouseX = e.clientX;
        this.LastMouseY = e.clientY;
        this.Draw();
    }

It doesn't work however, opera error console says "Type error: this.Draw() is not a function"

Why is this happening?

MZaragoza
  • 10,108
  • 9
  • 71
  • 116
Jake Freelander
  • 1,471
  • 1
  • 19
  • 26
  • And what is it? (use `console.log(typeof this.Draw)`). BTW, you miss semicolon after curly bracket ending Draw function. – Cromax Jun 21 '14 at 16:03
  • Heh, so it looks like Opera is contradicting itself... Have you tried to add missing semicolon (also to `onMouseMove` and I presume other functions)? – Cromax Jun 21 '14 at 16:09
  • yes i did just now (wasn't aware they needed it) but no change – Jake Freelander Jun 21 '14 at 16:11
  • 2
    I assume you've bound that method as an event handler, which means `this` is the element to which the handler is bound. – cookie monster Jun 21 '14 at 16:15
  • @Cromax: No Opera is not contradicting itself. The OP is doing something else wrong; he probably has the `console.log(this.Draw);` in the wrong place. And a "missing" semicolon isn't going to make any difference here. – cookie monster Jun 21 '14 at 16:17
  • yes "addEventHandler(this.Container, "mousemove", this.onMouseMove);". addEventHandler is a function that tried various methods for various browsers. Also tried chrome error console which says that the type is function and "undefined type is not a function" – Jake Freelander Jun 21 '14 at 16:17
  • As I said above, `this` is going to be a reference to the Element that has the handler bound. – cookie monster Jun 21 '14 at 16:19
  • oh i misunderstood, no. this has a reference to the element to which the handler is bound but in itself is a custom class prototype. – Jake Freelander Jun 21 '14 at 16:21
  • @cookiemonster Well, looks like you guessed. By "further down the line" I assumed it is still the part of `Viewport`. – Cromax Jun 21 '14 at 16:23
  • @KarliRaudsepp: You've detached the method from the object that you want, and so the event handler caller sets it to the element. In your call to `addEventHandler`, you can do `this.onMouseMove.bind(this);`, though you'll need to patch it if you support old browsers. – cookie monster Jun 21 '14 at 16:24
  • @KarliRaudsepp check for the closures in JS. `this` can point to different objects depending on calling context. Cookiemonster's right. – Cromax Jun 21 '14 at 16:26
  • so if I'm getting this right, instead of resolving this.method when the event listener is added, it tries to resolve it when the event is triggered? – Jake Freelander Jun 21 '14 at 16:30
  • You might want to learn what the value of `this` is and how to set it for event handlers. If you create multiple instances of Viewport or would like to inherit from it with an easy way to extend it's functions you can use prototype. That and the value of `this` is explained here: http://stackoverflow.com/a/16063711/1641941 – HMR Jun 21 '14 at 16:46
  • @KarliRaudsepp: Correct. That's how it works for functions in JavaScript. The value of `this` is almost always determined by the caller of the function *(by how it's called)*, not the creator or how it's created. The caller of the event handler is the event system, which sets `this` to reference the element. – cookie monster Jun 21 '14 at 16:56

0 Answers0