设置Array元素会更改具有相同名称的所有元素

时间:2014-06-17 00:35:50

标签: javascript arrays

这是以下链接的后续帖子。我在那里得到了帮助,显示我的代码在jsfiddle上按预期工作,所以在创建嵌套数组并将对象推送到它们时,必须有一个我不理解的概念: Updating elemint in JSON updates ALL

这个问题听起来像是确切的问题,虽然在javascript中对我来说,我有但我无法解释如何将正确答案应用于我的用例: How to avoid referencing the same index in an array (Java)?

这个订购用户界面有点不正统,他们首先选择帐户,然后当他们选择任何产品后,必须将其添加到所有帐户。

My Array是JS:

runningOrdfers = {
"id": 1402846607011,
"status": "unsaved",
"accounts": [
    {
        "compid": 919759,
        "compname": null,
        "products": [
            {
                "BCINUM": "539504",
                "ITEMUNIT": "EA",
                "ORDERDETAILS": [
                    {
                        "SHIPDATEID": "69230",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "1"
                    },
                    {
                        "SHIPDATEID": "69231",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "2"
                    }
                ],
                "SHIPPINGCOMMENTS": ""
            }
        ]
    },
    {
        "compid": 920001,
        "compname": null,
        "products": [
            {
                "BCINUM": "539504",
                "ITEMUNIT": "EA",
                "ORDERDETAILS": [
                    {
                        "SHIPDATEID": "69230",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "1"
                    },
                    {
                        "SHIPDATEID": "69231",
                        "SHIPPERIODID": "2096",
                        "QUANTITY": "2"
                    }
                ],
                "POTEXT": "",
                "SHIPPINGCOMMENTS": ""
            }
        ]
    }
]

以下是我如何创建对象并将其追加到数组中。首先,创建一个新订单:

var runningOrders = {};

function createNewOrder(event) {
    var uniqueID  = uniqueIdentifier();
    var accounts = [];
    var products = [];
    runningOrders.id = uniqueID;
    runningOrders.status = "unsaved";
    runningOrders["accounts"] = accounts;
    runningOrders.accounts["products"] = products;
    selectAccountsTab(event);
}

然后将帐户添加到订单中:

    function addAccountToOrder(compID) {
    getAccount(compID);
    var thisAccount = {};
    var n = savedAccountByCompID.length;
    for (var i = 0; i < n; i++) {
        var accountListObject  = savedAccountByCompID[i];
        thisAccount.compid = +accountListObject.COMPID;
        thisAccount.compname = +accountListObject.COMPNAME;
        thisAccount.products = [];
        runningOrders.accounts.push(thisAccount);
    }   
}

最后按刚刚创建的顺序将产品添加到帐户中:

    function setProductSelected(bcinum){
    var thisProductSelected = {};
    var thisProduct = "bcinum" + bcinum;
    var thisProductData = productData[thisProduct];

    thisProductSelected.BCINUM = thisProductData.BCINUM;
    thisProductSelected.ITEMUNIT = thisProductData.ITEMUNIT;
    thisProductSelected.ORDERDETAILS = [];

    thisOrderDetails = {
        SHIPDATEID: "69230",
        SHIPPERIODID: "2096",
        QUANTITY: ""
    };
    thisProductSelected.ORDERDETAILS.push(thisOrderDetails);

    thisOrderDetails = {
        SHIPDATEID: "69231",
        SHIPPERIODID: "2096",
        QUANTITY: ""
    };
    thisProductSelected.ORDERDETAILS.push(thisOrderDetails);

    var a = runningOrders.accounts.length;
    for (var ii = 0; ii < a; ii++) {
        currAccount = runningOrders.accounts[ii];    //possible problem? Loping over accounts and pushing same object?
        currAccount.products.push(thisProductSelected);
    }
}

我的函数迭代并更新我导航到的索引的元素:

function updateComments(compID,bcinum,comment) {
    var accounts = runningOrders.accounts;
    var n = accounts.length;
    for (i = 0; i < n; i++) {
        if (accounts[i].compid == compID) {
            var p = accounts[i].products.length;
            for (ii = 0; ii < p; ii++) {
                if (accounts[i].products[ii].BCINUM == bcinum) {
                    accounts[i].products[ii].SHIPPINGCOMMENTS = comment;
                }   
            }       
        }
    }
}

当我调用我的更新功能时,它正在更新所有索引位置的SHIPPINGCOMMENTS而不是我想要更新的位置,这是基于compID:

updateComments(919759,539504, '越早');

1 个答案:

答案 0 :(得分:1)

无论可读性问题如何,这似乎都按照this jsbin中所示的设计工作。似乎还有其他事情要发生。

这是一个很好的例子,说明不变性如何能够带来很大帮助。围绕不可变数据结构设计代码可以减轻复杂性和与真实的混淆。遗憾的是,在JavaScript中(默认情况下)对象是通过引用而不是通过值来管理的,因此语言本身不直接支持不可变对象。较新的版本(ECMAScript 5)支持Object.freeze,但您需要在较旧/功能失常的浏览器中使用polyfill。

为了管理深层嵌套数据结构的复杂性,它可以帮助将数据封装在自定义对象(经典面向对象设计中定义的对象,尽管在JavaScript的情况下,这将是一个原型对象)。但是,这超出了原始问题的范围(请参阅prototypical object oriented design上的此博文)。