为什么此Javascript数组中的项目位于错误的单元格中?

为什么此Javascript数组中的项目位于错误的单元格中?,javascript,arrays,Javascript,Arrays,有人编写了这个(非常糟糕的)函数来将0-999之间的数值转换为英语单词 function getNumberWords(number) { var list = new Array(1000); list[000] = "zero"; list[001] = "one"; list[002] = "two"; list[003] = "three"; ///skip a few list[099] = "ninety nine"; list[100] = "one

有人编写了这个(非常糟糕的)函数来将0-999之间的数值转换为英语单词

function getNumberWords(number) {
  var list = new Array(1000);
  list[000] = "zero";
  list[001] = "one";
  list[002] = "two";
  list[003] = "three";
  ///skip a few
  list[099] = "ninety nine";
  list[100] = "one hundred";
  list[101] = "one hundred and one";
  ///skip a few more
  list[997] = "nine hundred and ninety seven";
  list[998] = "nine hundred and ninety eight";
  list[999] = "nine hundred and ninety nine";
  return list[number];
}
这里有一个相当奇怪的bug,我似乎无法找出它的原因。某些元素(但不是所有元素)放置在错误的单元格中

我试着显示列表的内容,结果显示了一个非常有趣的结果:

> list.toString();
"zero,one,two,three,four,five,six,seven,ten,eleven,twelve,thirteen,fourteen,
fifteen,sixteen,seventeen,twenty,twenty one,twenty two,twenty three,twenty four,
twenty five,twenty six,twenty seven,thirty,thirty one,thirty two,thirty three,
thirty four,thirty five,thirty six,thirty seven,forty,forty one,forty two,"
///(skip a few)
"sixty six,sixty seven,seventy,seventy one,seventy two,seventy three,seventy four,
seventy five,seventy six,seventy seven,,,,,sixty eight,sixty nine,,,,,,,,,
seventy eight,seventy nine,eighty,eighty one,eighty two,eighty three,eighty four,"
///(and so on)
也就是说,元素0-7具有预期值。元素68、69和78-999也具有预期值。元素64-67和70-77为空。元件8-63的值不正确


这到底是怎么回事?为什么15个单元格是空的,56个单元格不正确,其余的单元格正确?

在Javascript中
022
表示
22
是八进制(
18
是十进制)


0前缀在JavaScript中表示八进制,因此
022
是八进制:

022 = 2*8^1+2*8^0 = 18

由于第一个索引i 0,18给出了第19个元素。

在非严格代码中以
0
开头的数字文字可能会导致该数字被解析为八进制文字(基数8)。例如,
010
被解析为一个值为
8
的数字

八进制文字现在已被弃用,在严格模式下将不会被解析为八进制,请使用
“use strict”

并非所有浏览器都支持严格模式,因此现在只需更改代码以确保数字不以0开头,或将其包装为字符串:

list[  21 ] = "something"
list["022"] = "something else";

字符串之所以起作用是因为八进制数。

0
开头的数字文字被解释为八进制值(如果可以的话)-即以8为基数的数字。在、、和许多其他语言中都是如此

现在,base-8
22
是base-10
18
,因此您没有访问您认为是的元素。您的前八个数组元素很好,因为base-8
0
自然也是base-10
0
,以此类推直到
7
。像
069
这样的值不会引起混淆,因为它不能表示base-8中的任何内容,所以Javascript会返回base-10。恶心


我建议改为使用间距进行对齐:

function getNumberWords(number) {
  var list = new Array(1000);
  list[  0] = "zero";
  list[  1] = "one";
  list[  2] = "two";
  list[  3] = "three";
  ///skip a few
  list[ 99] = "ninety nine";
  list[100] = "one hundred";
  list[101] = "one hundred and one";
  ///skip a few more
  list[997] = "nine hundred and ninety seven";
  list[998] = "nine hundred and ninety eight";
  list[999] = "nine hundred and ninety nine";
  return list[number];
}

我还建议创建一个新函数,动态生成字符串;在JavaScript中,以
0开头的数字被解释为八进制(以8为基数)

例如,
010==8

奇怪的是,JavaScript会将数字解释为十进制(以10为基数),即使它有一个八进制前缀,如果数字不可能达到八进制


例如,
08==8

来完成这个想法--22的八进制是2*8+2=18的十进制,这是数组的第19个元素(因为第一个元素在索引0处)。@Ted谢谢,将结果添加到我的答案中。
22的八进制实际上是
18的十进制,但它是第十九个元素,因为数组是零索引的。不总是这样。如果JavaScript不能强制转换为八进制,它将强制转换为十进制。例如,
08
强制执行
8
。@Paul:很抱歉。我写得很快,因为我知道我在赛跑;-)修复。这是八进制文字被弃用的原因之一。这不仅让他们感到困惑,而且这种怪癖让他们更加困惑。他们应该从一开始就抛出一个错误。
function getNumberWords(number) {
  var list = new Array(1000);
  list[  0] = "zero";
  list[  1] = "one";
  list[  2] = "two";
  list[  3] = "three";
  ///skip a few
  list[ 99] = "ninety nine";
  list[100] = "one hundred";
  list[101] = "one hundred and one";
  ///skip a few more
  list[997] = "nine hundred and ninety seven";
  list[998] = "nine hundred and ninety eight";
  list[999] = "nine hundred and ninety nine";
  return list[number];
}