JavaScript数组是特殊的对象,用数字索引模拟线性结构但遵循对象属性访问规则;遍历推荐for循环或map/filter等函数式方法;修改用push/pop最高效,清空用length=0;判断数组唯一可靠方式是Array.isArray()。

JavaScript数组是什么:不是“类数组”,是真正的对象
JavaScript数组是特殊的对象,不是传统意义上的连续内存块。它用数字索引(0、1、length属性)模拟线性结构,但底层仍遵循对象属性访问规则——比如arr[0]本质是读取属性名"0"的值。
这意味着:
- arr[-1]不会报错,只是返回undefined(因为对象允许任意字符串键)
- arr["length"]和arr.length等价,但arr["0"]比arr[0]多一次字符串转换
- 稀疏数组(如let a = []; a[100] = 1;)真实占用内存极少,length为101但只有1个元素
遍历数组的5种写法:别无脑用for…in
for...in会遍历所有可枚举属性,包括原型链上新增的方法或意外挂载的字符串键(如arr.foo = "bar"),导致跳过元素或重复执行。安全遍历只推荐以下几种:
for (let i = 0; i :最兼容,适合需要索引或中途break的场景-
for (const item of arr):ES6+,不暴露索引,但支持break/continue,且能正确处理NaN等值 -
arr.forEach((item, index) => {...}):语义清晰,但无法用break中断,且不返回新数组 -
arr.map()/arr.filter():函数式首选,但注意它们返回新数组,原数组不变 -
Array.from(arr, callback):当需要转换类数组(如arguments、NodeList)时更可靠
修改数组内容的陷阱:push/pop vs splice vs length赋值
看似都能增删元素,但行为差异极大:
-
arr.push(x)和arr.pop()是原子操作,返回新长度/被删元素,性能最优 -
arr.splice(start, deleteCount, ...items)可任意位置增删改,但会改变原数组,且返回被删除元素组成的数组(空数组表示没删任何东西) -
arr.length = 0清空数组最快,但arr.length = 5会在末尾补undefined(不是null),且不触发delete操作 - 直接赋值
arr[10] = x会扩大length,中间空位全是undefined,用in操作符检测会返回false
const arr = [1, 2, 3]; arr[5] = 6; console.log(arr.length); // 6 console.log(4 in arr); // false console.log(arr[4]); // undefined
判断是否为数组:instanceof不可靠
跨iframe或不同JS环境时,arr instanceof Array可能返回false(因构造函数不同)。唯一可靠方法是:
立即学习“Java免费学习笔记(深入)”;
-
Array.isArray(arr):ES5+标准方案,所有环境都支持 -
Object.prototype.toString.call(arr) === "[object Array]":ES3兼容方案,但冗长 - 避免用
typeof arr === "object"或arr.constructor === Array,前者对null也成立,后者易被篡改
稀疏数组、类数组、TypedArray(如Uint8Array)都不是Array,Array.isArray()能准确区分。










