JSON 对象中的数组 属性 通过 foreach 更新 - 更新所有键

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

我在这件事上有点紧张。我正在尝试通过 foreach 循环构建一个 JSON 对象数组。它工作得很好——除了一个 属性。我遇到困难的 属性 - 是一个在每个循环期间更新的数组。在第一个循环中,数组将为空。在第一个循环结束时,我添加一个值以为下一个循环做准备。在下一个循环中 - 创建一个新的 JSON 对象以添加到数组中。当我添加数组 属性 时,它还会更新之前的键。有点像 st运行ge。最终结果是,对于每个数组键(JSON 对象),'excludedUsers' 数组是相同的。

    ( 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++;

        }

    }

})();

如果你 运行 - 这个,我发现控制台有以下输出。 (注意:观看 属性 'excludedUsers')......

循环 #0

数组推送前:[{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[ ],"count":1,"name":"user1"}]

数组推送后:[{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[ 57],"count":1,"name":"user1"}]

循环#1

数组推送前:[{"usersId":57,"type":"user","disabled":"disabled","excludedUsers":[ 57],"count":1,"name":"user1"},{"usersId":58,"type":"user","disabled" :null,"excludedUsers":[57],"count":2,"name":"user2"}]

数组推送后:[{"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"}]

您在构建的每个对象中都引用了相同的数组实例。

userSelects[idx].excludedUsers = excludedUsers; 不会将 excludedUsers 数组复制到对象的新数组中,它会将对原始数组的引用分配给 userSelects[idx].excludedUsers.

如果你想克隆数组你可以使用Array.slice()做一个浅拷贝:

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