1

My code

for each(var enemy in RhythmGame.npcs) {
    if(this.hitTestObject(enemy)) {
        enemy.step(distance, axis, origin);
        enemy.damage(power);
    }
}

works fine until I put it in a function

separate();
function separate():void {
    for each(var enemy in RhythmGame.npcs) {
        if(this.hitTestObject(enemy)) {
            enemy.step(distance, axis, origin);
            enemy.damage(power);
        }
    }
}

and then I get the error

TypeError: Error #1006: hitTestObject is not a function.

I've found that this is referring to [object global] when it's in the function rather than the class instance it should be. Why would this happen? What don't I understand here about how scope works?

to_the_sun
  • 63
  • 6
  • Diagnose it: **trace(this);** **trace(typeof(this));** **trace(getQualifiedClassName(this));** **trace(this is DisplayObject);** for both cases and compare (and update your question). – Organis Sep 14 '17 at 22:42
  • Good call. It does indeed lose track of what `this` is. – to_the_sun Sep 14 '17 at 23:10
  • Do you define this function inside of the other function? – Organis Sep 15 '17 at 05:40
  • Anonymous (or inline) functions are always in the global scope of the application. Defined functions will be in the scope of the object where they are declared. Try to specify "private function" or "public function" instead. Here is a good explanation on that: https://stackoverflow.com/questions/33200045/what-object-global-is-exactly-when-this-is-accessed-inside-a-nested-or-inli – Philarmon Sep 15 '17 at 08:25
  • Why do you need to use "this" in `if(this.hitTestObject(enemy))`? Shouldn't the Main class code be handling hit-detection of instances of _hero versus enemy(s)_? That way you can use your actual instance names inside the function (which is now at Main code). – VC.One Sep 15 '17 at 09:21
  • @organis Yes I did and that seemed to be the problem. – to_the_sun Sep 19 '17 at 14:56
  • @Philarmon You're right, this was the issue. I had already tried that but it wouldn't allow it because `The private attribute may be used only on class property definitions.` – to_the_sun Sep 19 '17 at 15:11
  • @VC.One This is a good suggestion. Right now there's only certain functions that _could_ cause collisions and so it just seems more efficient to handle hit detection then than check every frame for it in the main class. – to_the_sun Sep 19 '17 at 15:33

1 Answers1

2

I've found that this is referring to [object global] when it's in the function rather than the class instance it should be. Why would this happen? What don't I understand here about how scope works?

This is the expected behavior if your function is a closure and not a method. I'm guessing the code you posted is itself contained in a function or perhaps a class method, and might be called later as a callback or something.

From the docs on function scope:

The main difference between a function closure and a bound method is that the value of the this keyword in a bound method always refers to the instance to which it was originally attached, whereas in a function closure the value of the this keyword can change.

Aaron Beall
  • 49,769
  • 26
  • 85
  • 103