Skip to content Skip to sidebar Skip to footer

Scope (I Think?!) Challenge In JavaScript

Using CreateJS, I have output a canvas with instances of various objects, animating in various ways. Almost all is working ok, except for one issue, which I think is a scope issue,

Solution 1:

The problem you're having is that you iterate over your pulsars incrementing i along the way and adding those event listeners. So when your listers actually fire, they use myParent (mind your likely typo sometimes using underscore in front of it and sometimes not) variable which was last set to the last pulsar when your for loop completed (last value of i);

You'll have to change this piece of code

myParent.pulse = function() {
    if (myParent.isPulsing == false) {
        myParent.isPulsing = true;
        myParent.__frame = 1
        var tween = createjs.Tween.get(myParent).to({__frame:65}, 1500).call(myParent.resetPulse);
        tween.addEventListener("change", function() {
            myParent.gotoAndStop(myParent.__frame);
        });
    }
}

to this:

myParent.pulse = (function(parent) {
    return function() {
        if (parent.isPulsing === false) {
            parent.isPulsing = true;
            parent.__frame = 1
            var tween = createjs.Tween.get(parent).to({__frame:65}, 1500).call(parent.resetPulse);
            tween.addEventListener("change", function() {
                parent.gotoAndStop(parent.__frame);
            });
        }
    };
})(myParent);

What this change does it creates a new function scope capturing current value of myParent and storing it in local variable (parameter) parent and then returning a function that uses this new captured value.

Maybe I've captured even too much in this and I should only create a new function scope for the tween.addEventListener function call. You should know which part need capturing. My code captures much more code than likely required so it should work just as well, but it may seem confusing after a while when you'll get back to it introducing some change.

Therefore reduce scoping to the minimum set of statements like:

myParent.pulse = function() {
    if (myParent.isPulsing == false) {
        myParent.isPulsing = true;
        myParent.__frame = 1
        var tween = createjs.Tween
            .get(myParent)
            .to({__frame:65}, 1500)
            .call(myParent.resetPulse);
        tween.addEventListener("change", (function(parent) {
            return function() {
                parent.gotoAndStop(parent.__frame);
            };
        })(myParent));
    }
}

But as mentioned this may not work as it uses __frame variable of the last myParent pulse instance. So you may end up with my first code change.


Post a Comment for "Scope (I Think?!) Challenge In JavaScript"