Trouble with 'this.' keyword

For developers using the Construct 2 Javascript SDK

Post » Wed Jan 18, 2012 7:50 pm

I'm having some trouble getting this.something to reference what I want it to reference. I've read through this to help me:
My problem is that when I try to call this.runtime.trigger in certain locations in my code, it tells me that it can't call method trigger of undefined. So this.runtime obviously isn't pointing where I want it to point.
Here's what I have:
instanceProto.onCreate initiates a websocket. When that socket receives a message, I want it to store data from the message in an object that my conditions and expressions will be able to see. Originally I had this:
instanceProto.onCreate = function() {
    //Other stuff
    var socket = new WebSocket(//My server's address
    //socket stuff
    socket.onmessage = function(evt) { =;

That wouldn't work, presumably because the 'this.' in '' refers to 'socket'. In order for my expressions to be able to reference the data as, this would need to refer to... instanceProto? Say I want the following operation to work:
cnds.thisIsACondition = function(indexOfWantedData) {
     if([indexOfWantedData] > 17) {
          return true;
     return false;

I've gotten the conditions to read from the data object correctly using this setup:
instanceProto.onCreate = function() {
    socket.onmessage = function(evt) {

instanceProto.updateData = function(data) { = data;

So this works. Marvelous! My conditions will read this correctly. Then I tried adding in the triggers, changing the last function to this:
instanceProto.updateData = function(data) { = data;
    this.runtime.trigger(cr.plugins_.MyPlugin.prototype.cnds.thisIsATrigger, this);

And I get errored out, with a "cannot call trigger of 'undefined'" thing.
(I currently can't get the exact error message since I'm not on the computer I have the work on, but I can post the exact error message later today if necessary)

So. If anyone knows why this.runtime isn't defined inside a function of instanceProto, despite the fact that this looks just like code I see in, for example, the Mouse plugin's onMouseDown trigger, I would love the help.
Posts: 3
Reputation: 581

Post » Wed Jan 18, 2012 7:55 pm

I think you have to use self instead of this
septeven2012-01-18 19:56:57
Passionate developer

If my work helped you to make your project, please consider making a donation :)
Posts: 631
Reputation: 11,047

Post » Wed Jan 18, 2012 10:37 pm

No, 'instanceProto' does not refer to your instance, it prefers to the instance's prototype. You can store data to it because javascript allows you to store data in any object, but it is a different object to your actual instance. It's sort of the object the instance 'inherits' methods from. More on prototypes - it's a really weird part of javascript, took me a while to get my head round it myself.

I think in your first example 'this' is actually just the global scope, because

[code]socket.onmessage = function (e)
{ = 5;

is basically equivalent to

[code]function temp(e)
{ = 5;
socket.onmessage = temp;[/code]

where it's more obvious that 'this' does not refer to anything. A good example of the solution is the Mouse object, which attaches a function to mousedown that uses a closure to permanently reference 'this' from the calling scope:

[code]     jQuery(document).mousedown(
          (function (self) {
               return function(info) {
                    // this is the real function -
                    // use 'self' instead of 'this'

It's a bit fiddly syntax, but that is the correct solution. As you can see it's easiest just to call another function so you can use a real 'this' instead of keeping using 'self'.
Scirra Founder
Posts: 25,282
Reputation: 200,833

Return to Javascript SDK

Who is online

Users browsing this forum: No registered users and 0 guests