0

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);
}
3
  • 3
    There is no block scope in javascript, only functions defines scope Commented May 9, 2013 at 3:41
  • 1
    What's out? You can loop arrays and objects with jQuery's $.each which creates a new scope. Commented May 9, 2013 at 3:42
  • You can learn more about JavaScript Hoisting Commented May 9, 2013 at 3:51

3 Answers 3

2

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]));
}
Sign up to request clarification or add additional context in comments.

Comments

0

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
})();

Comments

0

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]));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.