我有以下HTML:

<input type = "text" id = "pick"> <input type = "submit" value = "Submit" onclick = "guessWord()">


那会运行我的js函数,该函数在第一次调用时可以正常工作(与不相关的打ic)。但是,如果我更改了文本并再次提交却没有重新加载我的初始if / else语句行为不正确。具体来说,if / else应该检查用户输入的单词是否在数组中。它在第一次调用时可以正常工作,但之后即使不该跳转到else块。

这是js(对于包含整个功能,我们事先表示歉意,通常只要求我提供比最初多的代码):

function guessWord() {

  var comWords, match, compWord =  "";
  var possWords = dictFive;
  var firstFive = ["vibex", "fjord", "nymph", "waltz", "gucks"]; // note: right now choosing any of these words results in unexpected behavior -- either it doesn't accept them or it freezes.
  var inputWord = document.getElementById("pick").value.toLowerCase().replace(/\s+/g, '');

  if (possWords.includes(inputWord)) { // checks to see if the user inputted word is in our dictionary.i f not, requests a different word.

    // start game loop:

    // in order to try and get as much information as possible in the first few turns I start by guessing the five words in firstFive[]: vibex, fjord, nymph, waltz, gucks. together, these words give us information about 25 letters.

    for (let d = 0; d < inputWord.length; d++) { // this loop will run for the length of the inputted word, making it scaleable so in the future the program could accept shorter or longer words. within the current scope it will always be 5.

      compWord = firstFive[d]; // the computers word will loop through each word in firstFive[].

      if (inputWord === compWord) { // if the word matches the user inputted word:

        document.getElementById("otpt").innerHTML = "Your word was: " + firstFive[d] + ". I guessed it in " + (d + 1) + " turns.";
        return;

      } else { // if the word is not the user inputted word, then:

        comWords = (inputWord + compWord).split('').sort().join(''); // we combine the users word with the comps word and sort them by character.
        match = comWords.length - comWords.replace(/(\w)\1+/g, '$1').length; // match produces a numerical value for how many letters matched between both words.

        for (let e = 0; e < possWords.length; e++) { // loop to cycle through our dictionary.

          for (let f = 0; f < inputWord.length; f++) { // loop to cycle through all the different match options.

            if (match === 0) { // if there are no matches we can:

              if (possWords[e].includes(firstFive[f])) { // go through the dict and get rid of every word that has letters in common with the word.

                possWords.splice(e, 1);

              }

            } else if (match === f) { // if there's at least one letter in common:

              comWords = (possWords[e] + compWord).split('').sort().join(''); // as we cycle through the dict, pick each available word, combine and sort with the chosen word,
              var matchFive = comWords.length - comWords.replace(/(\w)\1+/g, '$1').length; // and then find how many letters match.

              if (matchFive != match) { // any words in dict that have a different match value can be deleted.

                possWords.splice(e, 1);
              }
            }
          }
        }
      }
    }

    // once we've worked through the words in firstFive[] we start guessing randomly.

    for (let a = 0; a < possWords.length; a++) { // the loop max is set to the length of the array because that's the maximum amount of time the guessing can take.

      compWord = possWords[Math.floor(Math.random() * possWords.length)]; // choose a random word.

      if (compWord === inputWord) { // check if the random word is the inputted word. if it is:

        document.getElementById("otpt").innerHTML = "Your word was: " + compWord + ". I guessed it in " + (a + 5) +  " turns. I had " + possWords.length + " remaining words that were possible matches.";
        return;

      } else { // while the word still isn't correct:

        comWords = (compWord + inputWord).split('').sort().join(''); // again, we join and sort it.
        match = comWords.length - comWords.replace(/(\w)\1+/g, '$1'); // find its match value.

        for (let c = 0; c < inputWord.length; c++) { // loop through inputted word's length to check all letters.

          if (match === 0) { // again, no matches we can safely delete all words with those letters.

            if (possWords.includes(compWord[c])) {
              possWords.splice(c, 1);

            }

          } else if (match === c) { // if match is higher than 0:

            for (let g = 0; g < possWords.length; g++) {

              comWords = (possWords[g]+ compWord).split('').sort().join('');
              matchAll = comWords.length - comWords.replace(/(\w)\1+/g, '$1');

              if (match != matchAll) {

                possWords.splice(g, 1);

              }
            }
          }
        }
      }
    }

      } else { // If the user inputted word was not in our dictionary, requests a different word:

    document.getElementById("otpt").innerHTML = "Please choose a different word.";

      }
    }


(对于上下文,dictFive是一个位于单独文件中的数组。)代码试图通过检查匹配的字母数来猜测用户输入的单词,然后在无法匹配的情况下从主数组中拼接出这些单词,因此该数组possWords以大约2500个单词开头,并在函数结束时缩小到几百个单词。据我所知,该函数应该在每次调用时正确地重置var,但是我猜它不是出于某种原因吗?

最佳答案

每次调用该函数时,都会对dictFive数组进行splice d。

设置possWords = dictFive,然后在以后拼接possWords时,由于两个变量都引用相同的数组,因此您也要拼接dictFive。然后,第二次运行该函数,dictFive仍处于其拼接状态。代替设置possWords = dictFive,请尝试制作阵列的副本。这样,您将在不影响原始dictFive的情况下拼接副本。您可以通过possWords = dictFive.slice()克隆数组。

var dictFive = [0,1,2,3,4]; // Just an example of whatever dictFive might be
var possWords = dictFive; // This makes possWords refer to the same thing as dictFive
possWords.splice(0, 1); // Splicing the array at whatever point
possWords // [1,2,3,4] because the 0th element was spliced out
dictFive // also [1,2,3,4] because both dictFive and possWords are the same array


比较一下

var dictFive = [0,1,2,3,4];
var possWords = dictFive.slice(); // This makes a copy of the array instead of referencing the original dictFive
possWords.splice(0, 1);
possWords // [1,2,3,4];
dictFive // Now, this array is still [0,1,2,3,4] because only the possWords array was spliced. dictFive wasn't affected.

08-19 09:12