javascriptarraysfunctionobjectpreserve

Preserve Object State when passed into queue of functions (Javascript)


Been trying to figure out a way to preserve my object state when pushing into a function. Sample code below:

window.queue = window.queue || [];

var some_data = {
    "object_number":1
}

queue.push(function(){console.log("1:",some_data)});

var some_data = {
    "object_number":2
}

queue.push(function(){console.log("2:",some_data)});

// Code I Cannot Change
for (var i = 0; i < queue.length; i++) {
    queue[i]();
}

Result of the queue execution is:

1: {object_number: 2}
2: {object_number: 2}

Can you see how when the queue is parsed (I can't change this code - it's controlled by someone else) it looks up the latest version of 'some_data'?

Any idea how to preserve the state of the object of when it was passed in? Desired result is:

1: {object_number: 1}
2: {object_number: 2}

Thanks!


Solution

  • You can use the following variant, which will create closure with a local variable (value) each time:

    var some_data = {
        "object_number":1
    }
    
    queue.push(((value) => () => console.log("1:",value))(some_data));
    
    var some_data = {
        "object_number":2
    }
    
    queue.push(((value) => () => console.log("2:",value))(some_data));
    

    In this case, after overwriting some_data, value does not change, since it is a separate variable. But note that changing the content of some_data will also change the content of value (then maybe you need copying of some_data before each push):

    var some_data = {
        "object_number":1
    }
    
    queue.push(((value) => () => console.log("1:",value))(some_data));
    
    var some_data = {
        "object_number":2
    }
    
    queue.push(((value) => () => console.log("2:",value))(some_data));
    
    some_data.object_number = 1;
    
    for (var i = 0; i < queue.length; i++) {
        queue[i]();
    }
    
    // 1: { object_number: 1 }
    // 2: { object_number: 1 }