在JavaScript中设置布尔变量时出现不可预知的行为[严格模式下的深度复制]

时间:2014-06-12 14:25:09

标签: javascript boolean windows-8.1 windows-store

function computerSetManapool(cost) {
    var splittedCost = cost.split(',');    
    for (var i = 0; i < splittedCost.length; i++) {                      
        if (splittedCost[i] === "CL") {
            for (var j = 0; j < computerLands.length; j++) {
                if (!computerLands[j].tapped) {
                    computerLands[j].tapped = true;
                    console.log(computerLands[j].name + " gets tapped");
                    break;
                }
            } 
        }
     }
}

我对这一小段代码有点麻烦,它是一个Windows应用商店应用,虽然我没有使用像WinJS库或jQuery那样的东西。 特别是这条线让我担心:

 computerLands[j].tapped = true;

我在Visual Studio中对此进行了调试,而j的值为1.因此,计算机范围[1] .tapped应该设置为true。

相反,它设置了computerLands [1] .tapped = true AND computerLands [3] .tapped = true。 它不会每次都发生,但很多次,因此我无法看到问题所在。

computerLands是一个最初为空的数组,然后将其动态推送到其中。

如果有人甚至不知道这可能是什么问题,我将非常感激。

编辑:这是填充computerLands的代码:

function computerTurn() {                                   
     untapAll("computer");
     drawCards(1, "computer");
     for (var i = 0; i < computerHand.length; i++) {             
          if (computerHand[i].type === "land") {
             var container = document.getElementById("computerLandsContainer");
             var newItem = document.createElement("div");                               
             newItem.id = computerLandsID;
             computerLandsID++;
             newItem.style.backgroundImage = "url("+computerHand[i].image+")";
             newItem.style.backgroundSize = "100%";
             var btn1 = document.createElement("button");
             btn1.id = "tapButtonComputer";                                              
             btn1.innerText = "˜";
             newItem.appendChild(createEnlargeButton(newItem,"computer"));
             newItem.appendChild(btn1);
             container.appendChild(newItem);
             computerLands.push(computerHand[i]);
             console.log("Computer plays: " + computerHand[i].name);
             computerLands[computerLands.length - 1].id = newItem.id;
             var index = computerHand.indexOf(computerHand[i]);
             computerHand.splice(index,1);
             break;
             }
      }
 }

实际的就是这样:

computerLands.push(computerHand[i]);

将其推入computerLands后,它将通过splice()从computerHand中删除。

var index = computerHand.indexOf(computerHand[i]);
computerHand.splice(index,1);

最后我找到了一个解决方案,我从这个页面得到了它:http://social.msdn.microsoft.com/Forums/windowsapps/en-US/f79b2e68-15a9-4d5e-8aad-e15f78d94840/how-do-i-clone-an-object?forum=winappswithhtml5

它描述了如何在Windows应用商店应用中进行深层复制(我发现在Windows应用商店应用严格模式下不允许使用http://james.padolsey.com/javascript/deep-copying-of-objects-and-arrays/这个其他解决方案),基本上您创建了一个新对象并将每个属性复制到其中。现在,这是我的新工作代码:

function populateComputerLands() {
    for (var i = 0; i < 4; i++) {
        //computerLands.push(availableComputerCards[0]);    <--- old code

        var objectToCopy = availableComputerCards[0];      // new code
        var newObject = Object.create(Object.getPrototypeOf(objectToCopy));
        var newObjectProperties = Object.getOwnPropertyNames(objectToCopy);
        var propertyName;
        for (var p in newObjectProperties) {
            propertyName = newObjectProperties[p];
            Object.defineProperty(newObject, propertyName, Object.getOwnPropertyDescriptor(objectToCopy, propertyName));
        };
        computerLands.push(newObject);
    }
}

0 个答案:

没有答案