0

I am really struggling with concept of scope in my code.

I am simply trying to create a 'callback' function which will add a className to a variable. As it's inside a function, I am passing the global variable as parameters to the callback function using the concept of closure (still dont understand how closure works).

var ePressCuttingsArray = $(".cPressCuttings");
var eSelectedPressCuttingsArray = [];
var iIndexArray  = [];
for (var i = 0; i < 7; i++) {
    var iIndexArrayValue;
    // two conditions being checked in while loop, if random no. is not in global array (iIndexArray) & i var is equal to eSelectedPress... array 
    while (jQuery.inArray(((iIndexArrayValue = Math.floor(Math.random() * 14) + 1), iIndexArray) === -1) 
        && (i === eSelectedPressCuttingsArray.length))
    {
        // to push a value at a position from array ePressCut... into eSelectedPress... array
        eSelectedPressCuttingsArray.push(ePressCuttingsArray[iIndexArrayValue]);
        // run a function to addClass to the recently pushed value in eSelectedPress... array
        (function (i) {
            $(eSelectedPressCuttingsArray[i]).addClass("cPressCuttingsDisplay0" + i)
        } (i) );
        iIndexArray.push(iIndexArrayValue);
    }
}

Could someone explain why the closure func. is not performing correctly, i.e. it always successfully add the className "cPressCuttingsDisplay00", but doesnt follow that up with a className of "cPressCuttingsDisplay01" for the next loop iteration.

6
  • 2
    I don't see any sort of callback or need for closures here. Your anonymous function doesn't do anything different than if you just had its body directly in your loop. Commented Jan 20, 2012 at 3:18
  • 3
    Could you explain what this code is supposed to do? I suspect there's a way to simplify it. Commented Jan 20, 2012 at 3:21
  • 1
    Note that a new scope for variables is only created by entering a function, not within blocks like for loops or if blocks. Also see: bonsaiden.github.com/JavaScript-Garden/#function.closures Commented Jan 20, 2012 at 3:25
  • @Jacob, I have an array created "ePressCuttingsArray" in the first line, which has about 16 values. I want to randomly select 6 values from this array & pass it into "eSelectedPressCuttingsArray" array (created in 2nd line), while making sure that no value is repeated. Whenever a value (div reference) is passed into the 2nd array "eSelectedPressCuttingsArray", it should be given an incremental className (e.g. cPressCuttingsDisplay00, cPressCuttingsDisplay01, etc upto 6), this is where Im trying to be clever & use closures & callbacks etc, but I suspect my main problem is with scoping. Cheers Commented Jan 20, 2012 at 3:36
  • 1
    Nope, it's one of the notable JS "quirks" / horrible design decisions to be aware of. The other is probably "variable hoisting", where variables (no matter where in your function the var keyword is) are always "hoisted" to the very top of the function body. The assignment isn't, but the declaration of it is. Stupid, but true. Commented Jan 20, 2012 at 3:51

1 Answer 1

1

You should be able to accomplish your goal by using a for loop:

var ePressCuttingsArray = $(".cPressCuttings").makeArray();
var eSelectedPressCuttingsArray = [];
for (var i = 0; i < 7; i++) {
    var idx = Math.floor(Math.random() * ePressCuttingsArray.length);
    var selectedItem = ePressCuttingsArray[idx];
    selectedItem.addClass('cPressCuttingsDisplay0' + i);
    eSelectedPressCuttingsArray.push(selectedItem);
    ePressCuttingsArray.splice(idx, 1);
}
Sign up to request clarification or add additional context in comments.

3 Comments

thankyou, was looking into this. Logic of 'no repeating the same no.', for which I used while loop above. Here is the amended code: for (var i = 0; i < 7; i++) {var idx = Math.floor (Math.random() * ePressCuttingsArray.length); while (jQuery.inArray (idx, iIndexArray) === -1) {var selectedItem = ePressCuttingsArray[idx]; $(selectedItem).addClass("cPressCuttingsDisplay0" + i); eSelectedPressCuttingsArray.push (selectedItem); iIndexArray.push (idx); } }
The issue now is with the while loop in which I am using the condition that if idx value is NOT found in array eSelectedPressCuttingsArray, then do the rest of the expression. However, now when it encounters a repeat no, it just passes over the no. & the i value continues to increment. While is perhaps not the correct solution but I didnt quite grasp how splicing would solve the repetition problem...
Sorted it, its not very elegant but hey... var ePressCuttingsArray = $(".cPressCuttings"); var iIndexArray = []; for (var i = 0; i < 6; i++) { var idx = Math.floor (Math.random() * ePressCuttingsArray.length); if (jQuery.inArray (idx, iIndexArray) === -1) { var selectedItem = ePressCuttingsArray[idx]; $(selectedItem).addClass("cPressCuttingsDisplay0" + i); eSelectedPressCuttingsArray.push (selectedItem); iIndexArray.push (idx); } else { i--; } }

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.