0

I'm working on a small retro-style side-scrolling space shooter game (or, that's the theory anyway) and I've recently moved over to using IIFEs for managing my separate 'classes'.

However, most of the examples I've seen tend to use var when declaring variables, E.g, var x = 0. I'm wondering though, is it possible to use this.x = 0 and if so, are there any benefits or drawbacks?

I've tried googling it, and can't find much on the subject, which leads me to think it's a non-issue.

My classes are as follows;

var Player = function () {
    // ------------------------------------------------------------------------------------------------
    // PLAYER VARIABLES
    // ------------------------------------------------------------------------------------------------
    var w = 50;
    var h = 50;
    var x = 0;
    var y = 0;
    var color = 'white';
    var projectiles = [];

    // ------------------------------------------------------------------------------------------------
    // BIND EVENTS TO THE GLOBAL CANVAS
    // ------------------------------------------------------------------------------------------------
    Canvas.bindEvent('mousemove', function(e){
        y = (e.pageY - Canvas.element.getBoundingClientRect().top) - (h / 2);
    });

    Canvas.bindEvent('click', function(e){
        createProjectile(50, (y + (h / 2)) - 10);
    });

    // ------------------------------------------------------------------------------------------------
    // FUNCTIONS
    // ------------------------------------------------------------------------------------------------
    var createProjectile = function(x, y){
        projectiles.push({
            x: x,
            y: y
        })
    };

    var update = function(){
        for(var p = projectiles.length - 1; p >= 0; p--){
            projectiles[p].x += 10;

            if(projectiles[p].x > Canvas.element.width)projectiles.splice(p, 1);
        }
    };

    var render = function () {
        Canvas.context.fillStyle = color;
        Canvas.context.fillRect(x, y, w, h);
        console.log(projectiles.length);

        for(var p = 0; p < projectiles.length; p++){
            Canvas.context.fillStyle = 'red';
            Canvas.context.fillRect(projectiles[p].x, projectiles[p].y, 20, 20);
        }
    };

    // ------------------------------------------------------------------------------------------------
    // Exposed Variables and Functions
    // ------------------------------------------------------------------------------------------------
    return{
        update: update,
        render: render
    }
}();
Lewis
  • 3,479
  • 25
  • 40
  • `this` will point to the lexical scope, mostly window in non strict mode. In strict mode `this` will be `undefined`. – Rajaprabhu Aravindasamy Mar 29 '16 at 16:12
  • @RajaprabhuAravindasamy: `this` doesn't point to *lexical scope*. You can't reference scope in JS (exception: global scope and scope created by `with` statements because they are backed by objects). – Felix Kling Mar 29 '16 at 16:23
  • @FelixKling Oh thank you. `//'this' value here function test(){ //how can i tell the this value outside of this function? }` I used to tell that that is the lexical scope. I am running out of technical terms. :( – Rajaprabhu Aravindasamy Mar 29 '16 at 16:29
  • 1
    Your IIFE does not look like it's declared properly. It should be `var Player = (function() {})();` An IIFE is just a normal function call. See [How the Value of This is Set](http://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676) for the six ways that the value of `this` is determined. – jfriend00 Mar 29 '16 at 16:33
  • @jfriend00 Thanks =) – Lewis Mar 29 '16 at 16:41

1 Answers1

2

are there any benefits or drawbacks?

The drawbacks are that in strict mode, you will get a runtime error (because this is undefined).
In non-strict mode, this will refer to window, so this.x = ... creates a global variable (which is what you want to avoid with the IIFE in the first place I guess).

There are no benefits.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Thanks for your answer =) As someone who struggles with 'scope', this seems like strange behaviour to me. As a regular constructor, var player = function(){}, `this` would be scoped to player. Turning it in to an iife though, with the simple addition of (), changes this? – Lewis Mar 29 '16 at 16:20
  • Global variable crash can be avoided. Won't that comes under benefits? – Rajaprabhu Aravindasamy Mar 29 '16 at 16:20
  • @RajaprabhuAravindasamy: The question is if there are any benefits of using `this.x = ...` in an IIFE, not the benefits of IIFEs themselves. – Felix Kling Mar 29 '16 at 16:22
  • @Lewis: An IIFE is nothing but a function call. `foo()` and `new foo()` are two different ways to call a function. The value of `this` is primarily determined by *how* a function is called. `foo()`, `bar.foo()`, `new foo()`, `foo.call(x)` can all result in different values for `this`. – Felix Kling Mar 29 '16 at 16:22
  • I'm confused why the OP is immediately invoking like this. It makes no sense. – Andy Mar 29 '16 at 16:25
  • @Andy I may have gone about this backwards, as I'm still learning all this (through doing) - but hopefully it'll make more sense in context. I wanted the player and it's update/render methods to be immediately available to a Game class inside another file. https://jsfiddle.net/cqsrwbqz/ – Lewis Mar 29 '16 at 16:30