为什么项目在这个Javascript数组的错误单元格中

Why are items in the wrong cells in this Javascript array?

本文关键字:错误 单元格 数组 Javascript 项目 为什么      更新时间:2023-09-26

有人写了这个(非常糟糕的(函数来将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];
}

这里有一个相当奇怪的错误,我似乎无法找出原因。某些元素(但不是所有元素(被放置在错误的单元格中。

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

> 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个单元格不正确,其余单元格正确?

0开头的数字文字被解释为八进制值(如果可以的话(—即以8为基数的数字。Javascript、C、C++、PHP、Perl、Bash和许多其他语言都是这种情况。

现在,基于8的22是基于10的18,所以您不会访问您认为的元素。您的前八个数组元素很好,因为自然地,基数为8的0也是基数为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中,022在八进制中表示22(十进制中为18(。

维基百科上的八进制数字系统

在非严格代码中用0启动数字文字可能会导致该数字被解析为八进制文字(基数为8(。例如,010被解析为具有值8的数字。

八进制文字现在被弃用,并且在严格模式下不会被解析为八进制,使用"use strict":

function a() {
    alert(010);
    // -> 8
} 
function b() {
    "use strict";
    alert(010);
    // -> 10
} 

并不是所有的浏览器都支持严格的模式,所以现在只需更改代码以确保数字不会以0开头,或者用字符串包装:

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

字符串之所以有效,是因为八进制数不是强制的。

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

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

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

在JavaScript中,以0开头的数字被解释为八进制(以8为底(。

例如,010 === 8

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

例如,08 === 8