How to use controller-scoped version of this to refer to the current controller in JS?

Summary

Setting root as a property of your controller in order to save you from having to type var root = this in your controller methods is not useful. You should just do var root = this when needed because the property ultimately is not a net benefit over var root = this.

Explanation

The first answer you got is a partial answer. kingshuk basak is right that what you are doing is setting a root variable in the global space. See, if you do this:

function foo() {
  something =  1;
}

you are setting something in the global space. To make it local to your function you need var:

function foo() {
  var something =  1;
}

The lack of var in the first snippet does not make JavaScript interpret it as this.something, even if the function is part of a prototype.

kingshuk basak suggesting you make it part of your controller by using this. This works, yes but then you have to access it using this because that's how JavaScript works. So the naive way to use it would be:

uiController = {
  root: 0,
  init: function() {
    this.root = this;
    this.root.doSomething(); // You havve to use `this` here too!!
  },

  doSomething: function() {
     this.root.somethingElse();
  }
}

From what your question says, you are just trying to save yourself from having to write var root = this. So root won't ever change. But think about this for a second.

What you are doing is adding a property named root to this, which has the exact same value as this. In order to access root, which has the same value as this, you already need to have this. So there's no good reason for this.root to exist. As explained above, if you do this.root = this, then each access to it must be this.root so you've not appreciably reduced your burden. Not only that, but doing this.root.foo() requires an additional indirection at execution: root has to be fetched from this first.

You could do this:

uiController = {
  root: 0,
  init: function() {
    var root = this.root = this;
    root.doSomething();
  },

  doSomething: function() {
     var root = this.root;
     root.somethingElse();
  }
}

But again, this does not reduce the burden.

You should just do var root = this when you need it.


The reason is simple. The 'root' variable of the uiController is overWritten by the heroController as both are declared in the global namespace. Try different names as root1 and root2 for uiController and heroController, it will work fine.

Note : Ideally you should not pollute the global namespace to avoid such problems. Use closures if necessary.

This is what you have to do :

uiController = {

    root: 0,
    init: function() {

         this.root = this;

        // Call functions
        root.doSomething();

    },

    doSomething: function() {

    }
}