vincent thorpe
vincent thorpe

Reputation: 294

JavaScript constructor: is this a property or a variable?

I was surfing on the canvas element, to use with JavaScript games and I found this code:

function component(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    ctx = myGameArea.context; // **why not: var ctx= myGameArea.context ???**
    ctx.fillStyle = color;
    ctx.fillRect(this.x, this.y, this.width, this.height);
}

My question is what is ctx a property? Or a private variable?

ctx is not declared or even used, outside of this constructor (like: var ctx). It is only inside this code.

I hear if you set a variable with a value directly without the var reserved word, you are declaring a global. But that ctx variable is not being used outside that constructor, so is useless?

Also they do the same thing when setting the key property to an instance of an object.

The entirely code...

var myGamePiece;

function startGame() {
    myGameArea.start();
    myGamePiece = new component(30, 30, "red", 10, 120);
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 480;
        this.canvas.height = 270;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
    }
}

function component(width, height, color, x, y) {
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;    
    ctx = myGameArea.context;
    ctx.fillStyle = color;
    ctx.fillRect(this.x, this.y, this.width, this.height);
}

Upvotes: 1

Views: 192

Answers (3)

Stavros Zavrakas
Stavros Zavrakas

Reputation: 3063

Yes, it seems that it is a pretty bad practice not to declare it at least as var. If a variable is not declared with var/let/const, the Javascript engine will define them in the global namespace and can have unknown side effects. It is a bit worrying that there is an access to the myGameArea global (?) variable. Why is this not injected into the constructor? Something like that would have been clearer:

function component(width, height, color, x, y, myGameArea) {
  this.width = width;
  this.height = height;
  this.x = x;
  this.y = y;

  var ctx = myGameArea.context;
  ctx.fillStyle = color;
  ctx.fillRect(this.x, this.y, this.width, this.height);
}

Upvotes: 0

harmic
harmic

Reputation: 30587

If you refer to a variable inside the body of a function, JS will search the scope chain of the function to find the variable.

If the variable was not declared inside the function itself, then it will look in the scope of any enclosing function(s), then finally in the global scope.

From the fragment you presented we can't see if ctx is declared in an enclosing function, or is a global variable, although you say it is not used outside the constructor which implies it is not declared anywhere. On balance I would say it the author accidentally used a global instead of a local variable.

As an aside: I recommend using a tool such as jshint to pick up errors such as using global variables by mistake.

Upvotes: 0

Jorge Cabot
Jorge Cabot

Reputation: 191

If that function is by itself and not inside another function then chances are ctx is a global variable. If a local variable is desired var ctx should be used instead, but will not be accessible from the outside. If access to the ctx variable is desired then it it should be declared as this.ctx.

If it is inside another function then it could be a captured variable:

function parent() {
    var ctx = parentArea.context;

    function component(width, height color, x, y) {
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
        ctx = myGameArea.context; // References parent's ctx variable
        ctx.fillStyle = color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}

Upvotes: 1

Related Questions