JavaScript如何判断数组索引是否为整数?

4
似乎 JavaScript 的数组索引实际上都是字符串,所以 a[0]a['0'] 是相同的,而 a[1.0] 不等于 a[1],而是等于 a['1.0']。 但同时,数组有一个 length 属性;当您修改整数键的值时,它会自动更新。那么 JavaScript 如何知道键是整数并且需要更改长度呢? 如果我这样做:
var a = 4/2;
var b=8/4; 
var c = 2; 
var d= 1*2;

这些代码 arr[2], arr[0+2], arr[1*2], arr[a], arr[b], arr[c], arr[d] 是同一个东西吗?

通常我们会像这样在循环中访问数组:

for (i=0; i<100; i++) {
  arr[i]=1;  // this is a[0],a[1] right?
  arr[i+0.0]=1;  // is this a[0] or a['0.0'] ?
}

如果我写下这句话:
for (i=0.1; i<100; i+=0.1) {
  arr[i*10]=1;  // what does it do?  a[1] = 1, a[1.0]=1 or a[1.00000] = 1 ?
}

循环中的赋值语句是做什么用的?

略微离题:为什么您需要这样做?有什么实际价值呢? - Damask
3个回答

4

首先,在JavaScript(ES5)中,不存在"Integer"这个概念。JavaScript(ES5)只有数字。

其次,在JavaScript中,存在大量的隐式类型转换。以下是一个例子:

if(1=='1') console.log('very truthy');

如果使用双等号,它会将 '1' 转换为数字然后比较新值 (1) 是否等于 1 (结果为 true),然后记录字符串 '非常真实的'。

如果使用三等号,就不会发生隐式类型转换。

if(1==='1') console.log("this won't get logged");

使用三个等号可以避免类型转换的发生。

接下来,当你将一个值添加到一个整数索引的数组中时,该索引将会被更新为您给定的值,并且长度也会随之更新。

var a = [];
a[0] = 0
a[1] = 1; 
a[2.0] = 2;
//[undefined, 1, 2]

当您试图更新不是整数(1.1)的索引时,它会将任何内容转换为字符串(1.1变为'1.1'),然后在数组中添加一个新的自定义属性并设置其值。数组的自定义属性不会影响其长度。
var a = [];
a[1.1] = 1.1;
a.prop = "property";
//[], empty array
console.log(a.prop, a['1.1']); //"property",1.1

当你向JS数组添加自定义属性时,它会改变对象的形态,使其像对象字面量一样操作。

因此,在这种情况下,你最终得到了一个类似于数组/对象字面量混合体的对象。注意:如果你向JS数字或字符串添加自定义属性,它们并不会被转换为对象字面量。这种行为是JS数组特有的。


最后一段话对我来说完全没有意义。 - Musa
@Musa 你有没有想要特别询问的部分,还是我们就这样结束了? - frosty

3

JavaScript数组实际上不是数组,而是JavaScript对象,具有原型方法,使其表现得像数组。

arr['one'] = 1是有效的JavaScript代码。

arr.length的工作原理只是通过查找数组的键,找到最大的数字(JavaScript实际上不处理整数,只处理浮点数),并返回该数字加1。

请尝试:

var arr = [];

arr.one = 1;
arr[8] = 1;
console.log(arr.length);

@user1787576 是的,因为在JavaScript中8.0和8之间没有区别。 - Ord
不能确定,但一个数组也是一个对象。在Javascript引擎下,它可能被实现为一个带有使用整数键的数组的对象。因此可以转换为整数而不丢失信息的键将存储在数组中,而像2.3、1.001这样的键将存储在未计入数组的对象部分中。 - user1600124
当您尝试添加自定义属性到数组时,该数组会变异为类似于对象文字的对象。在此之前它只是一个数组。 - frosty
@aaronfrost 什么是“类似对象字面量的对象”? - Musa
@Musa 它是一个对象,您可以像对象字面量一样设置属性。但它也具有 Array.prototype 的所有功能,如 slice、join、shift 等。无论您如何界定其语义,它都是一个既可以作为数组又可以作为对象字面量的数组。 - frosty
显示剩余3条评论

1

从在Chrome的开发工具中尝试,我认为你的断言并不是完全正确的。我发现:

arr[0] == arr[0.0] == ar[0.0000] == arr["0"]

但是

arr[0] != arr["0.0"]
arr[0.0] != arr["0.0"]

看起来数组在内部所做的是对你给定的索引调用.toString(),并将其作为实际索引使用。请注意:

(0).toString() == "0"
(0.0000).toString() == "0"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接