1. 数组的本质
- 本质上,数组也是一个对象
- JavaScript 语言规定,对象的键名一律为字符串,所以,数组的键名其实也是字符串。之所以可以用数值读取,是因为非字符串的键名会被转为字符串
typeof [1, 2, 3] // "object"
let arr = [1,2,3,4]
arr['0'] // 1
arr[0] // 1
2. length属性
- JavaScript 使用一个32位整数,保存数组的元素个数。这意味着,数组成员最多只有 4294967295 个(2^32 - 1)个,也就是说length属性的最大值就是 4294967295
- 如果人为设置length为不合法的值,JavaScript 会报错
- 由于数组本质上是一种对象,所以可以为数组添加属性,但是这不影响length属性的值
[].length = -1 // Uncaught RangeError: Invalid array length
[].length = 2**32 // Uncaught RangeError: Invalid array length
[].length = 'hello' // Uncaught RangeError: Invalid array length
----
let arr = [1,2,3]
arr['name'] = 'lewis'
arr // [1, 2, 3, name: "lewis"]
arr.length // 3
3. 数组的遍历
- for循环
- for...in:不仅会遍历数组所有的数字键,还会遍历非数字键
- forEach()方法
4. 数组的空位
- 当数组的某个位置是空元素,即两个逗号之间没有任何值,我们称该数组存在空位(hole)
- 如果最后一个元素后面有逗号,并不会产生空位
- 数组的空位不影响length属性
- 数组的空位是可以读取的,返回undefined
- 使用delete命令删除一个数组成员,会形成空位,并且不会影响length属性
- 数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过
let arr = [1,,3,]
arr.length // 3
arr[1] // undefined
delete arr[0] // true
arr[0] // undefined
arr.length // 3
----
var a = [, , ,]
a.forEach(function (x, i) {
console.log(i + '. ' + x) // 不产生任何输出
})
for (var i in a) {
console.log(i) // 不产生任何输出
}
Object.keys(a) // []
5. 类数组
- 如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类数组”(array-like object)
- 典型的“类数组”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串
- 数组的slice方法、Array.from()、[...arrayLike]可以将“类数组”变成真正的数组
var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}
obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function
----
// arguments对象
function args() { return arguments }
var arrayLike = args('a', 'b')
arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false
// DOM元素集
var elts = document.getElementsByTagName('h3')
elts.length // 3
elts instanceof Array // false
// 字符串
'abc'[1] // 'b'
'abc'.length // 3
'abc' instanceof Array // false
---
var arrLike = {
0: 1,
1: 3,
2: 5,
3: 7,
4: 9,
length: 5
}
console.log(arrLike)
let arr = Array.from(arrLike)
console.log(arr)
let arr2 = Array.prototype.slice.call(arrLike)
console.log(arr2)
let arr3 = [...arrLike]
console.log(arr3)