为什么此 JavaScript switch 语句(在 for 循环内)保留其前一次迭代的值?

Why does this JavaScript switch statement (which is inside a for loop) keep it's values from a previous iteration?

function convertToRoman(num) {
  //seperate the number in to singular digits which are strings and pass to array.
  var array = ("" + num).split(""), 
      arrayLength = array.length, 
      romStr = "";

  //Convert the strings in the array to numbers
  array = array.map(Number);

  //Itterate over every number in the array
  for (var i = 0; i < array.length; i++) {

    //Calculate what power of ten the digit is by minusing it's index from the array length and passing it to variable "tenToPowerOf"
    var tenToPowerOf = arrayLength - array.indexOf(array[i]) - 1,
        low = "",
        mid = "",
        upp = "";

    //Set the low, mid and high variables based on their tenToPowerOf value
    switch (tenToPowerOf) {
    case 0:
      low = "I";
      mid = "V";
      upp = "X";
      break;
    case 1:
      low = "X";
      mid = "L";
      upp = "C";
      break;
    case 2:
      low = "C";
      mid = "D";
      upp = "M";
      break;
    case 3:
      low = "M";
      mid = "¯V";
      upp = "¯X";
      break;
    }

    //Check for digit value and add it's Roman Numeral value (based on it's power from the above switch statement) to romStr
    //The problem is, switch "remembers" the value of low, mid and high from the last time it itterated over the number. Thus 99 becomes "XCXC" and not "XCIX". 
    switch (array[i]) {
    case 1:
      romStr += low;
      break;
    case 2:
      romStr += low.repeat(2);
      break;
    case 3:
      romStr += low.repeat(3);
      break;
    case 4:
      romStr += low + mid;
      break;
    case 5:
      romStr += mid;
      break;
    case 6:
      romStr += mid + low;
      break;
    case 7:
      romStr += mid + low.repeat(2);
      break;
    case 8:
      romStr += mid + low.repeat(3);
      break;
    case 9:
      romStr += low + upp;
      break;
    case 10:
      romStr += upp;
      break;
    default:
      break;

    }

  }
  //return array;
  return romStr;
}

convertToRoman(99);

因为Javascript使用函数闭包并且您的循环默认情况下不会重置值,换句话说,for 内部的变量仍然存在于它外部。

for 循环中声明为 var 的变量不会在每次迭代时重置,它与 switch.

无关

尝试将其粘贴到您的控制台中 -

for (var i = 1; i <= 10; i++)
{
    console.log('before', i, j);
    var j = i * 10;
    console.log('after', i, j);
}

请注意,在第一个循环中,"before" jundefined,之后总是落后一步。如果您再次 运行 相同的代码,j 将从 100

开始

为了解决这个问题,我会在循环开始时将 j 设置为 null(或其他一些合理的值)-

for (var i = 1; i <= 10; i++)
{
    var j = null;
    console.log('before', i, j);
    j = i * 10;
    console.log('after', i, j);
}

在我看来,您的问题在于使用 array.indexOf(array[i]) 来计算幂。你猜怎么着,如果你的数组中有两次相同的值,返回第一个找到的索引,而不是你的当前元素的索引。

猜猜你当前元素的索引是多少? → i
不需要 indexOf.

switch无关。