为什么在几次迭代后我得到“未定义”?

时间:2018-04-27 10:24:11

标签: javascript for-loop undefined

下面的代码会发生一件奇怪的事情。代码运行顺利,只有一个例外 - 经过几次迭代后,我得到“未定义”。

您可以通过运行几次来测试它。首先,您将获得常规输出(三个随机城市),然后在某些时候您将获得“未定义”。这种情况发生在不到10次迭代中。

为什么这样做?我错过了什么?

var coolWords = ["Amsterdam", "Berlin", "Sofia", "Prague", "Lisbon", "London", "Malaga", "Copenhagen", "Milan"];
    
var newList = [];
    
function niceTripleCombo(coolWords) {
  for (let i = 0; i < 3; i++) {
    var combo = coolWords[Math.floor(Math.random()*coolWords.length)];
    newList.push(" " + combo);
  };
};
    
function iterator(x) {
  if (newList[0] !== newList[1] && newList[1] !== newList[2] && newList[1] !== newList[3]) {
    return newList;
  } else {
    return niceTripleCombo(coolWords);
  }
};
    
    console.log(iterator(niceTripleCombo(coolWords)));

4 个答案:

答案 0 :(得分:0)

当newList数组具有以下值时,

 [" Berlin", " Berlin", " London"]

或类似,其中一个数组元素相同,迭代器中的if条件失败,并且您正在执行

niceTripleCombo(coolWords)

没有返回值,因此返回undefined。

答案 1 :(得分:0)

应该在newList方法中返回

niceTripleCombo数组。

&#13;
&#13;
var coolWords = ["Amsterdam", "Berlin", "Sofia", "Prague", "Lisbon", "London", "Malaga", "Copenhagen", "Milan"];

var newList = [];

function niceTripleCombo(coolWords) {
  newList.length = 0; // Empty the array before starting
  for (let i = 0; i < 3; i++) {
    var combo = coolWords[Math.floor(Math.random()*coolWords.length)];
    newList.push(" " + combo);
  };
  return newList; //Returning an array.
};

function iterator(x) {
  if (newList[0] !== newList[1] && newList[1] !== newList[2] && newList[1] !== newList[3]) {
    return newList;
  } else {
    return niceTripleCombo(coolWords);
  }
};

console.log(iterator(niceTripleCombo(coolWords)));
&#13;
&#13;
&#13;

答案 2 :(得分:0)

关于您的代码的几点说明:

  • 迭代amnything,你只是检查一次
  • 如果结果是得到一个独特的三个单词,如果随机发生器没有给你正确的数字,这种方法会浪费很多周期。
  • 如果要传递一个数组,为什么要将它作为全局变量?这将使你的迭代器毫无意义。
  • 您猜测函数没有返回值 - 因此返回undefined

我的建议是:

var coolWords = ["Amsterdam", "Berlin", "Sofia", "Prague", "Lisbon", "London", "Malaga", "Copenhagen", "Milan"];

function niceTripleCombo( list ) {

  // Make a copy of the list so we don't modify the original.
  let words = list.slice();
  let result = [];
  
  for( let i = 0; i < 3; i++ ){
    
    // Use splice to get a word out of your copy array
    // It also removes it from the array,
    // so next time we cannot guess this word anymore.
    result.push(
      words.splice( Math.floor( Math.random() * words.length ), 1 )[ 0 ]
    );
    
  }
  
  return result;
  
};

console.log( niceTripleCombo(coolWords) );

这将始终返回三个唯一单词的列表,它通过从数组中选择一个随机单词,将其从数组中删除并将其添加到答案中,然后使用现在更短的数组重复来完成。这样你只需要运行这个周期三次次而不是可能无限量,如果随机发生器不在您身边。

答案 3 :(得分:0)

让我们考虑一下这个测试。

首先,从iterator(niceTripleCombo(coolWords))调用console.log()

现在将调用niceTripleCombo(coolWords)

启动niceTripleCombo(coolWords)

现在进入循环,

i = 0,假设我们得到newList = [" Milan"]

i = 1,假设我们得到newList = [" Milan", " London"]

i = 2,假设我们得到newList = [" Milan", " London", " London"]

niceTripleCombo的终结(coolWords)

最后我们有米兰,伦敦,伦敦

现在在iterator()

由于我们有2伦敦,if将失败,else将会运行。

现在这是第一个错误,您没有将newList初始化为空。因此,当再次运行niceTripleCombo时,它会再添加三个城市。

例如,您可能会[" Milan", " London", " London", " Amsterdam", " Malaga", " Sofia"]

现在其次return niceTripleCombo(coolWords);不会返回任何值。

为什么它不会返回任何内容是因为,您返回的函数[niceTripleCombo(coolWords)]没有返回语句。

  

您的功能必须返回任何值或返回a   函数,该函数必须返回一个值。在你的情况下,   您在niceTripleCombo(coolWords)中没有返回声明   默认情况下,如果没有其他值,则js函数返回undefined   返回。

这就是你得到undefined的原因。

因此,请将else中的iterator更改为:

else {
  newList = [];
  niceTripleCombo(coolWords);
  return iterator();
}

现在你不应该undefined。接下来,无需将niceTripleCombo传递给iterator。由于您未使用niceTripleCombo内的iterator功能。

详细了解MDN中的returnreturn statement