简体   繁体   中英

Array property in JSON object updated via foreach - updates all keys

I'm kind of pulling my hair out on this one. I am trying to build an array of JSON objects via a foreach loop. It works great - except for one property. The property that I am having difficulty with - is an array that is updated during each loop. During the first loop, the array would be empty. At the end of the first loop, I add a value to prepare it for the next loop. During the next loop - create a new JSON object to add to the array. When I add the array property, it also updates the previous key. Kinda of strange. The end result, is for each array key (JSON Object), the 'excludedUsers' array is the same.

    ( function () {

    // Pre-populate User Permissions
    var userPermissions = $('.js-user-permissions').val();
    var numberOfSelects = 1;
    var count = 1;
    var arraySize;
    var viewHtml = '';
    var userSelects = [];
    var excludedUsers = [];

    if(userPermissions) {

        userPermissions = jQuery.parseJSON(userPermissions);
        // An array of JSON like:
        // [{ usersId=57, type="user"}, { usersId=58, type="user"}]

        arraySize = userPermissions.length;

        for(var idx = 0; idx < userPermissions.length; idx++) {

            userSelects[idx] = {};
            console.log("Loop #" + idx);

            // Set default value of select element
            userSelects[idx].usersId = userPermissions[idx].usersId;
            userSelects[idx].type = userPermissions[idx].type;
            userSelects[idx].disabled = arraySize == count ? null : 'disabled';
            userSelects[idx].excludedUsers = excludedUsers;
            userSelects[idx].count = numberOfSelects;
            userSelects[idx].name = "user" + numberOfSelects;
            numberOfSelects++;

            console.log("Before Array Push: " + JSON.stringify(userSelects));

            excludedUsers[idx] = userPermissions[idx].usersId;

            console.log("After Array Push: " + JSON.stringify(userSelects));

            count++;

        }

    }

})();

If you ran - this, I am finding the following output to the console. (NOTE: Watch the property 'excludedUsers').......

Loop #0

Before Array Push: [{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[],"count":1,"name":"user1"}]

After Array Push: [{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[57],"count":1,"name":"user1"}]

Loop #1

Before Array Push: [{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[57],"count":1,"name":"user1"},{"usersId":58,"type":"user","disabled":null,"excludedUsers":[57],"count":2,"name":"user2"}]

After Array Push: [{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[57,58],"count":1,"name":"user1"},{"usersId":58,"type":"user","disabled":null,"excludedUsers":[57,58],"count":2,"name":"user2"}]

You are referencing the same instance of the array in every object that you build.

userSelects[idx].excludedUsers = excludedUsers; does not copy the excludedUsers array into a new array for the object, it assigns a reference to the original array to userSelects[idx].excludedUsers .

If you want to clone the array you can use Array.slice() to do a shallow copy:

userSelects[idx].excludedUsers = excludedUsers.slice(0)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM