1

I'm confused about how to use, define, change and unset javascript object.

My javascript object is:

var Ship = function(){
    return {
        canvas: $('#area')[0],
        canvas_width: this.canvas.width,
        canvas_height: this.canvas.height,
        context: this.canvas.getContext("2d"),
        ship_image: new Image(),
        ship_width: null,
        ship_height: null,
        ship_x: 0,
        ship_y: 0,
        init: function() {
            this.ship_image.onload = function() {
                this.ship_width = this.width;
                this.ship_height = this.height;
                this.ship_x = (this.canvas_width / 2) - (this.ship_width / 2);
                this.ship_y = this.canvas_height - this.height;

                this.draw(
                    this.ship_x,
                    this.ship_y
                );
            }

            this.ship_image.src = "ship.gif";
        },
        draw: function(x, y) {
            this.context.drawImage(
                this.ship_image,
                x,
                y
            );
        }
    }
}();

When i execute this code like;

$(function(){
    Ship.init();
    Controller.init();
});

I get this error every time.

Uncaught TypeError: Cannot read property 'width' of undefined on line 4 (ship.js)

Uncaught TypeError: Ship is not a function on line 29 (index.html / Ship.init())

What should i do now?

1 Answer 1

4

The problem is that this.canvas doesn't point to the canvas property of the object ship, it points to global object window. You need to initialize canvas_width diferently, for example in init function. And the same thing with context:

var Ship = function () {
    return {
        canvas: $('#area')[0],
        ship_image: new Image(),
        ship_width: null,
        ship_height: null,
        ship_x: 0,
        ship_y: 0,
        init: function () {

            this.context = this.canvas.getContext("2d");
            this.canvas_width = this.canvas.width;
            this.canvas_height = this.canvas.height;

            this.ship_image.onload = function () {
                this.ship_width = this.ship_image.width;
                this.ship_height = this.ship_image.height;
                this.ship_x = (this.canvas_width / 2) - (this.ship_width / 2);
                this.ship_y = this.canvas_height - this.ship_image.height;

                this.draw(this.ship_x, this.ship_y);
            }.bind(this);

            this.ship_image.src = "ship.gif";
        },
        draw: function (x, y) {
            this.context.drawImage(this.ship_image, x, y);
        }
    }
}();
Sign up to request clarification or add additional context in comments.

5 Comments

context: this.canvas.getContext("2d"), this same :-)
How to reach draw function inside init? Because draw is; Uncaught TypeError: this.draw is not a function.
@R.CanserYanbakan Yes, indeed, there is one more problem with context. Check updated answer code. The thing is that inside this.ship_image.onload handler this points to image instance object. So you can simply bind this function to proper this and use this.ship_image.width instead of this.width.
Is it better to defined that context, canvas_width and canvas_height with default values and change that values in the init function?
Yes, you can define them first and then initialize in init, it's a matter of preference. context: null, canvas_width: null.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.