natbob1
natbob1

Reputation: 318

jquery callback anonymous function closure

I've declared the variable elem in both of the loops below; however, when the anonymous function in the first loop gets called (after the 400ms fadeOut effect is finished) the elem seems to refer to the value of elem which was assigned in the second loop. In other words, the code works correctly if you rename elem in the second loop to any other variable name.

Is there a way to make a closure around the anonymous function so that the value of elem is not changed in the context of the anonymous function?

for (var i = 0; i < outs.length; i++) {
  var elem = this.elementAtPoint(outs[i]);

  $(elem).fadeOut(400, function () {
    $(elem).removeClass("white black queen"); //UPDATE
    $(elem).show();
  });
  //$(elem).css("background", "red");
}

for (var i = 0; i < ins.length; i++) {
  var elem = this.elementAtPoint(ins[i]);
  var piece = this.board.pieceAt(ins[i]);

  $(elem).hide();

  $(elem).addClass(this.classForPiece(piece));

  $(elem).fadeIn(400);
}

Upvotes: 0

Views: 1123

Answers (3)

Coin_op
Coin_op

Reputation: 10718

I would avoid creating lots of closures inside loops, they would be inefficient as they create copies of the current scope. Instead I'd simply create a couple of extra functions then call them inside your loops:

var fadeInPiece = function(elem, piece){
  $(elem).hide();
  $(elem).addClass(this.classForPiece(piece));
  $(elem).fadeIn(400);
}

var fadeOutElem = function(elem){
  $(elem).fadeOut(400, function () {
    $(elem).removeClass("white black queen"); //UPDATE
    $(elem).show();
  });
}

for (var i = 0; i < outs.length; i++)
  fadeOutElement(this.elementAtPoint(outs[i]));

for (var i = 0; i < ins.length; i++)
  fadeInPiece(this.elementAtPoint(ins[i]), this.board.pieceAt(ins[i]));

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388316

You could use a anonymous self executing function

for (var i = 0; i < outs.length; i++) {
    (function(elem){
        $(elem).fadeOut(400, function () {
            $(elem).removeClass("white black queen"); //UPDATE
            $(elem).show();
        });
        //$(elem).css("background", "red");
    })(this.elementAtPoint(outs[i]));
}

Upvotes: 2

ltebean
ltebean

Reputation: 1019

in javascript, variable scope is decided by function, so you can wrap the two for loops in two function. a wrapper function example:

(function(){
    //put you for loop here
})();

Upvotes: 0

Related Questions