似乎JavaScript的数组索引实际上都是字符串,因此a[0]
与a['0']
相同,而a[1.0]
不是a[1]
而是a['1.0']
。
但与此同时,数组具有长度属性;当您修改整数键的值时,它将自动更新。那么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 ?
}
循环中的赋值是什么?
答案 0 :(得分:4)
首先,在JavaScript(ES5)中,没有“Integer”这样的东西。 JavaScript(ES5)只有Numbers。
其次,在JavaScript中有很多隐式类型转换正在进行中。这是一个例子:
if(1=='1') console.log('very truthy');
如果使用双等号,它会将'1'转换为数字,然后将新值(1)与1(将为真,1 == 1)进行比较,然后记录字符串'非常真实'。
如果使用三等号,则不会发生隐式类型转换。
if(1==='1') console.log("this won't get logged");
使用三等于防止类型转换发生。
接下来,当您向数组的整数索引添加一个值时,该索引会使用您告诉它的值进行更新,并且LENGTH将会更新。
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数组添加自定义属性时,它会将对象变为对象文字。
因此,在这种情况下,您最终会得到一个array-ish / object-literal-ish mashup对象。注意:如果将自定义属性添加到JS编号或字符串,它们不会转换为对象文字。您正在探索的此行为对于JS数组是唯一的。
答案 1 :(得分:2)
JavaScript数组实际上不是数组,它们是具有原型方法的JavaScript对象,这些原型方法会使它们像数组一样运行。 arr['one'] = 1
是有效的JavaScript。
arr.length的工作方式只是查看数组的键,找到最大的数字(JavaScript不是真正的整数,只是浮点数)并返回该数字+ 1.
尝试:
var arr = [];
arr.one = 1;
arr[8] = 1;
console.log(arr.length);
答案 2 :(得分:1)
在Chrome的开发工具中,我认为你的断言不是完全正确。我发现:
arr[0] == arr[0.0] == ar[0.0000] == arr["0"]
BUT
arr[0] != arr["0.0"]
arr[0.0] != arr["0.0"]
所以看来数组在内部执行的操作是在您给它的索引上调用.toString()
,并将其用作实际索引。请注意:
(0).toString() == "0"
(0.0000).toString() == "0"