4

看起来 JavaScript 的数组索引实际上都是字符串,所以和while is not buta[0]是一样的。但同时,数组有一个长度属性;当您修改整数键的值时,它将自动更新。那么 JavaScript 如何知道键是整数并且需要更改长度呢?如果我做:a['0']a[1.0]a[1]a['1.0']

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 ?
}

循环中的赋值是做什么的?

4

3 回答 3

4

对于初学者来说,在 JavaScript (ES5) 中,没有“整数”之类的东西。JavaScript (ES5) 只有数字。

其次,在 JavaScript 中有很多隐式类型转换。这是一个例子:

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

如果您使用双等号,它会将“1”转换为数字,然后将新值 (1) 与 1 进行比较(这将是真的,1 == 1),然后将记录字符串'非常真实'。

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

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'),然后将新的自定义属性添加到数组并设置值 on它。数组的自定义属性不会影响它的长度。

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 数组所独有的。

于 2012-10-31T06:25:08.643 回答
3

JavaScript 数组并不是真正的数组,它们是 JavaScript 对象,具有使它们像数组一样工作的原型方法。 arr['one'] = 1是有效的 JavaScript。

arr.length 的工作方式是简单地查看数组的键,找到最大的数字(JavaScript 并不真正做整数,只是浮点数)并返回该数字 + 1。

尝试:

var arr = [];

arr.one = 1;
arr[8] = 1;
console.log(arr.length);
于 2012-10-31T06:08:53.280 回答
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"
于 2012-10-31T06:16:02.077 回答