使用它们分配数组值时,javascript是否会对数字索引调用.toString?

时间:2014-03-26 08:23:25

标签: javascript arrays

我有一个长度为0的数组,无论出于什么原因,我决定为它添加属性。我可以使用括号表示法为数组赋予属性,如下所示:

array['name'] = 'keith';

属性'name' : keith将添加到数组的属性列表中。此外,就像对象使用括号表示法一样,括号内的表达式首先进行字符串化。所以,如果我要说array [undefined] ='42'(当然,没有人会这样做),undefined将被转换为字符串,我现在有另一个属性'undefined' : 42。 array.length仍为0,因为非整数键(也称索引)不计入长度。

现在,我有点困惑。在“正常”对象上,如果我这样做:myObject[10] = 10那么我将拥有一个具有属性'10' : 10的对象,属性名称10已被字符串化。根据我们刚才所做的,array['2'] = 'foo';应该将属性'2' : 'foo'添加到数组中,array[3] = 'bar';应该执行相同的操作:成为数组的属性而不计入长度。但是,当然,这两个语句只是将它们的值分配给数组中的相应索引。我不是在抱怨,因为这种行为更直观,我只是想知道我的逻辑在哪里导致我误入歧途。在阅读array[0] = 'cat';被有效评估为array[ (0).toString() ] = 'cat';

之后,我今天才学到了所有这些

3 个答案:

答案 0 :(得分:1)

来自Mozilla Developer resources

  

也可以引用JavaScript数组索引(例如,年[" 2"]而不是年[2]),尽管它没有必要。 2年内[2]由JavaScript引擎通过隐式toString转换强制转换为字符串。出于这个原因," 2"和" 02"将在year对象上引用两个不同的插槽,以下示例可能为真:

console.log(years["2"] != years["02"]);

基本上,如果你传递的是一个字符串(或int,因为它将被转换为字符串),它可以是一个整数(如' 0'),它将引用该整数的索引。如果不是,它将向您正在创建的Array对象添加属性,而不计算长度。

请注意手动增加数组的length创建新的空元素,尽管减少length实际上删除相应的数组末尾的元素。

对于您可能需要密集阵列(具有固定长度)的特定应用程序,请查看Typed Arrays


查看此示例(jsFiddle):

var test = new Array();
test[undefined] = 'undefined';
console.log(test);
console.log(test.length);

// This adds a property to the object 'test'
// Returns:
// [undefined: "undefined"]
// 0 

test['string'] = 'string';
console.log(test);
console.log(test.length);

// This adds another property to the object 'test'
// Returns:
// [undefined: "undefined", string: "string"] 
// 0 

test['00'] = 'zero 00';
console.log(test);
console.log(test.length);

// This adds yet another property to the object 'test',
// since 00 is not explicitly an int.
// Returns:
// [undefined: "undefined", string: "string", 00: "zero 00"] 
// 0

test['0'] = 'zero 0';
console.log(test);
console.log(test.length);

// This adds an element to the array 'test'
// Returns:
// ["zero 0", undefined: "undefined", string: "string", 00: "zero 00"] 
// 1

test[0] = 'zero 0 int';
console.log(test);
console.log(test.length);

// This overrides the element at index 0 in the array 'test'
// Returns:
// ["zero 0 int", undefined: "undefined", string: "string", 00: "zero 00"] 
// 1

答案 1 :(得分:1)

答案是肯定的。

数组也是对象,数组的索引也是对象的。

From the document

媒体资源名称

属性名称必须为字符串。这意味着非字符串对象不能用作对象中的键。任何非字符串对象(包括数字)都是通过toString方法 类型化为字符串。

答案 2 :(得分:1)

根据ECMAScript - 15.4,当且仅在以下情况下,特定值p被视为数组索引:

(p >>> 0 === p) && (p >>> 0 !== Math.pow(2, 32) - 1)

在你的情况下,你所知道的两个键被视为数组索引,因此计入数组的长度,这比最高索引高一个。