Please explain why this works

my code is below.

I do not understand why method fade works. when I call it from my init method, I pass sprite to it, and then fade is called from the sequence action again. when it is called again, it still has a reference to the sprite that I passed to it, and I do not understand why and how.

var MyLayer = cc.Layer.extend({
    batch: null,

    init: function () {
        this._super();

        var cache = cc.SpriteFrameCache.getInstance();

        cache.addSpriteFrames("Resources/sprites.plist");

        var sprite = cc.Sprite.createWithSpriteFrameName("frame-0.png");

        this.batch = cc.SpriteBatchNode.create("Resources/sprites.png");
        this.batch.addChild(sprite);
        this.addChild(this.batch);

        var frames = [];
        for (var i = 0; i < 6; i++) {
            var name = "frame-" + i + ".png";
            var frame = cache.getSpriteFrame(name);
            frames.push(frame);
        }

        this.index = 0;
        this.frames = frames;

        this.fade(sprite);

        return this;
    },

    fade: function (sprite) {
        var action = cc.Sequence.create(cc.FadeIn.create(1.0),
                                        cc.FadeOut.create(1.0),
                                        cc.CallFunc.create(this, this.fade));

        sprite.setDisplayFrame(this.frames[this.index]);
        sprite.runAction(action);

        this.index = (this.index + 1) % this.frames.length;
    }
});

I’ve faced with the similar question before. I think it relates to calling scope such that when you call runAction() you use “sprite” to call it, so the parameter passed in are in the realm or scope that “sprite” knows. And because runAction() is attached to that “sprite” so you still have access to the parent owner of that action (I don’t look into the cocos2d-html5 code, but this is what I believe it will be in terms of programming language and its behavior).

In additional,
I once tried to pass in a different variable such that (for example)

sprite.runAction(cc.CallFunc.create(this, this.fade, anotherSprite);

Whenever you do like that, you lost “anotherSprite” and it will be null in the function receiving the call. If it’s not the “sprite” itself, or primitive data type passing in, it will be null. I’m not sure about this behavior whether it’s a limitation on JS language or it should be that way though.