为什么此Javascript数组中的项目位于错误的单元格中?
有人编写了这个(非常糟糕的)函数来将0-999之间的数值转换为英语单词为什么此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
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-822
是base-1018
,因此您没有访问您认为是的元素。您的前八个数组元素很好,因为base-80
自然也是base-100
,以此类推直到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];
}