javascript在使用数字索引分配数组值时是否调用. tostring ?

Does javascript call .toString on numeric indices when using them to assign array values?

本文关键字:是否 调用 tostring 数组 分配 数字 索引 javascript      更新时间:2023-09-26

我有一个长度为0的数组,出于某种原因,我决定给它添加属性。我可以给数组分配属性,使用括号表示法,像这样:

array['name'] = 'keith';

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

现在,这是我有点困惑的地方。在"正常"对象上,如果我这样做:myObject[10] = 10,那么我将拥有一个具有属性'10' : 10的对象,属性名称10已被字符串化。根据我们刚才所做的,array['2'] = 'foo';应该将属性'2' : 'foo'添加到数组中,array[3] = 'bar';应该做同样的事情:成为数组的属性,而不计入长度。但是,当然,这两个语句只是将它们的值赋给数组中各自的索引。我不是在抱怨,因为这种行为更直观,我只是想知道我的逻辑把我引入了歧途。我今天读到array[0] = 'cat';被有效地评估为array[ (0).toString() ] = 'cat';后才知道这一切

来自Mozilla Developer资源:

也可以引用JavaScript数组索引(例如,years["2"]而不是years[2]),尽管这不是必要的。年中的2[2]被JavaScript引擎通过隐式toString转换强制转换为字符串。由于这个原因,"2"answers"02"将指向years对象上的两个不同的槽位,下面的示例可能为真:

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

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

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

对于非常特殊的应用程序,您可能需要密集数组(固定长度),请查看类型化数组。


看看这个例子(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

答案是肯定的。

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

从文档:

属性名称

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

根据ECMAScript - 15.4,一个特定的值p被认为是一个数组索引当且仅当:

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

在您的示例中,您提到的两个键被视为数组索引,因此计入数组的长度,它比最高索引高一个。