【问题标题】:Javascript Global Variables Are ResettingJavascript 全局变量正在重置
【发布时间】:2016-04-05 14:36:25
【问题描述】:

我正在尝试做的事情的总结:我制作了一个非常简单的游戏,它使用 do/while 函数和开关来检查你在哪个房间。如果你在房间 = 1,开关选择room1 并运行 room1() 函数。在房间内,你可以选择往哪个方向走。如果你选择北或东,door1() 或 door4() 函数会运行说“你想打开这扇门吗? " 您可以说“打开”并走进下一个房间,您的房间 = 1 将更新为新值。

出了什么问题:这一切都运行良好,并且功能(虽然它们有些臃肿)似乎可以正常运行。一个主要问题是每当我穿过一扇门时我的变量都会重置,所以我总是在房间 1,我的指南针总是等于 0,并且没有一个门或房间等于“已访问”(例如:room1V = 0)。

基本上,我穿过一扇门,最终又回到了 1 号房间,而不是 2 号或 4 号房间。

这是代码和演练:

    var room1V = 0; //room1  // these variables tell the computer whether I have 'visited' a room before.
    var room2V = 0; //room2
    var room3V = 0; //room3
    var room4V = 0; //room4

    var door1V = 0; //room1 - room2 // these variables tell the computer whether I have used a door before.
    var door2V = 0; //room2 - room3
    var door3V = 0; //room3 - room4
    var door4V = 0; //room4 - room1

    var compass = 0; // which side of the room am I on?
    var room = 1; // what room am I currently in?
    var reply = 1; // this is re-declared as a local variable in each function, and it works fine
    win = 0; // this will eventually tell the room-check do/while to stop

    // This do/while checks what room I am in:
    do {
        quit = 0;
        switch(room) {
            case '1':
                room1(compass,room1V);
                break;
            case '2':
                room2(compass,room2V);
                break;
            case '3':
                room3(compass,room3V);
                break;
            case '4':
                room4(compass,room4V);
                break;
        }
    } while (win != 1);

由于默认设置为 room = 1,因此 room1(compass,room1V) 函数将启动。

    function room1(compass,room1V) {
        if (room1V === 1) {
            console.log("You are in room 1 again.");
            document.write("You are in room 1 again." + "<br>");
            var reply = prompt("Where would you like to go? EAST, NORTH?");
            switch(reply.toLowerCase()) {
                case 'east':
                    compass = "east"; //because you are trying to open the east door, you will now see room1 from the east. If you make it through, your compass will update to 'west' because you will be on the west side of room2.
                    door1(compass,door1V);
                    break;
                case 'north':
                    compass = "north";
                    door4(compass,door4V);
                    break;
                default:
                    console.log("Something went wrong.");
                    document.write("Something went wrong." + "<br>");
            }
        } else {
            console.log("You are in room 1.");
            document.write("You are in room 1." + "<br>");
            room1V = 1;
            reply = prompt("Where would you like to go? EAST, NORTH?");
            switch(reply.toLowerCase()) {
                case 'east':
                    compass = "east";
                    door1(compass,door1V);
                    break;
                case 'north':
                    compass = "north";
                    door4(compass,door4V);
                    break;
                default:
                    console.log("Something went wrong.");
                    document.write("Something went wrong." + "<br>");
            }
        }
    }   // Working

如果我向“北”走,指南针会更新以显示我从哪个方向查看房间,并且 door4(room,door4V) 将运行。

    function door4(room,door4V) {
        if (door1V === 1) {
            console.log("You approach door 4 again.");
            document.write("You approach door 4 again." + "<br>");
            var reply = prompt("What would you like to do? OPEN, QUIT?");
            switch(reply.toLowerCase()) {
                case 'open':
                    if (room === 4) {
                       room = 1;
                       compass = "north";
                       console.log("You walk through door 4 into room 1...");
                       document.write("You walk through door 4 into room 1..." + "<br>");
                    } else {
                       room = 4;
                       compass = "south";
                       console.log("You walk through door 4 into room 4...");
                       document.write("You walk through door 4 into room 4..." + "<br>");
                       }
                    quit = 1;
                    break;
                case 'quit':
                    quit = 1;
                    break;
                default:
                    console.log("Something went wrong.");
                    document.write("Something went wrong." + "<br>");
            }
        } else {
            console.log("You approach door 4.");
            document.write("You approach door 4." + "<br>");
            var reply = prompt("What would you like to do? OPEN, QUIT?");
            switch(reply.toLowerCase()) {
                case 'open':
                    if (room === 4) {
                       room = 1;
                       compass = "north";
                       console.log("You walk through door 4 into room 1...");
                       document.write("You walk through door 4 into room 1..." + "<br>");
                    } else {
                       room = 4;
                       compass = "south";
                       console.log("You walk through door 4 into room 4...");
                       document.write("You walk through door 4 into room 4..." + "<br>");
                    }
                    quit = 1;
                    break;
                case 'quit':
                    quit = 1;
                    break;
                default:
                      console.log("Something went wrong.");
                      document.write("Something went wrong." + "<br>");
            }
        }
    }       // Working

此时,do/while 函数应该说:“哦!既然房间 = 4,你现在在房间 4。”但事实并非如此。 Room do = 4,但是当 do/while 重新运行时,我又回到了 room1,所有变量似乎都已重置。

【问题讨论】:

    标签: javascript function scope global-variables var


    【解决方案1】:

    您的变量“重置”的原因是 JavaScript 中的原语是按值传递的。在你的do-while循环中,你将变量room1V..room4V传递给函数room1..room4。变量是 JavaScript 中的基元,按值传递。这意味着在被调用函数中对它们所做的任何更改都不会反映在原始参数中。当您使用compassdoor4v 调用door4 函数时也是如此:这些变量是按值传递的。为了更好地理解这一点,请尝试阅读this chapter

    【讨论】:

    • 最简单的解决方法是创建一个不同的全局变量,以便 OP 可以设置它而不是局部变量
    【解决方案2】:

    您遇到了“可变阴影”问题 (Variable shadowing in JavaScript)

    var fancy = 0;
    
    function room1(fancy) {
      /* here, there are two variables with the name 'fancy' in scope */
      fancy = 1;
    }
    
    console.log(fancy); // 0
    room1();
    console.log(fancy); // 0
    

    您可以通过将 room1 参数更改为不同的名称来解决此问题:

    function room1(otherFancy) { fancy = 1; } 现在:

    console.log(fancy); // 0
    room1();
    console.log(fancy); // 1
    

    【讨论】:

      【解决方案3】:

      您永远不会更改房间变量的值以匹配新房间。它被设置在全局变量中并且不会改变。

      像这样在你的 do while 循环中更新你的房间:

      // This do/while checks what room I am in:
          do {
              quit = 0;
              switch(room) {
                  case '1':
                      room1(compass,room1V);
                      room = 1;
                      break;
                  case '2':
                      room2(compass,room2V);
                      room = 2;
                      break;
                  case '3':
                      room3(compass,room3V);
                      room = 3;
                      break;
                  case '4':
                      room4(compass,room4V);
                      room = 4;
                      break;
              }
          } while (win != 1);
      

      【讨论】:

        猜你喜欢
        • 2013-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多