数组的length属性
- 数组特殊的地方在于,只要你使用2的三十一次方减一的非负整数作为属性名,数组就会自动为你维护length属性的值
- JavaScript 数组的 length 属性是由它的 索引属性(即使用非负整数作为键的属性)动态维护的。如果你给数组分配一个非常大的索引值(如 2^31 - 1,即 2147483647),数组的 length 会自动更新为这个索引值加 1。这种行为是 JavaScript 数组的一种特殊机制。
1. 非负整数索引:
数组的索引必须是一个 非负整数,范围是 0 到 2^32 - 2(即 4294967294)。如果超出这个范围,属性不再被视为索引,而是普通对象的属性,数组的 length 也不会因此改变。
示例:
let arr = [];
arr[0] = "A"; // 合法索引
arr[1000] = "B"; // 合法索引,length 更新
console.log(arr.length); // 输出 1001
arr["1000000000000"] = "C"; // 超出索引范围,变成普通属性
console.log(arr.length); // 输出 1001(未更新)
console.log(arr["1000000000000"]); // 输出 "C"
2. 动态维护 length 属性:
当你为数组分配一个大于或等于当前 length 的索引时,length 属性会自动更新为 索引值加 1。
示例:
let arr = [];
arr[3] = "A"; // 分配索引 3
console.log(arr.length); // 输出 4(索引 3 + 1)
arr[999] = "B"; // 分配索引 999
console.log(arr.length); // 输出 1000
3. 极大的索引值:
当你分配一个非常大的索引(例如 2^31 - 1),JavaScript 仍然会动态维护 length。注意,索引的范围会受到最大内存的限制,实际操作可能会变得非常慢。
let arr = [];
arr[2147483647] = "Big"; // 分配索引 2^31 - 1
console.log(arr.length); // 输出 2147483648(索引值 + 1)
arr[0] = "Small"; // 修改索引 0
console.log(arr[2147483647]); // 输出 "Big"
console.log(arr.length); // 仍然是 2147483648
4. 索引与普通属性的区别:
只有符合数组索引规则的键(非负整数)会影响 length,其他属性不会影响。
示例:
arr[5] = "A"; // 合法索引
arr["test"] = "B"; // 非索引,作为普通属性
console.log(arr.length); // 输出 6(索引 5 + 1)
console.log(arr.test); // 输出 "B"
console.log(Object.keys(arr)); // 输出 [ '5', 'test' ]
5. 小结:
- 数组的索引必须是非负整数,范围在 0 到 2^32 - 2。
- 如果索引大于或等于当前 length,length 会自动更新为索引值 + 1。
- 超出范围的键会被视为普通对象属性,不影响数组的 length。
- 这种行为使数组在动态扩展时更方便,但需要小心处理极大的索引值,以免内存不足或性能下降。