JavaScript中数组和对象都是日常开发中高频使用的引用数据类型,二者在属性层面的设计既有共通性也存在明显差异,掌握这些特性和对应的处理技巧能大幅提升开发效率。

数组与对象属性的核心差异
属性定义方式不同
对象的属性是自定义的键值对,键可以是字符串或者Symbol类型,而数组的属性除了开发者自定义添加的额外属性外,核心元素是索引属性,索引本质是数值类型的特殊键,同时数组自带length这个内置属性。
我们可以通过下面的代码直观看到二者的属性区别:
// 对象属性定义
const user = {
name: '张三',
age: 25,
'user-id': '1001' // 字符串键可以包含特殊字符
};
// 数组属性定义
const arr = [10, 20, 30];
arr.customProp = '额外属性'; // 数组可以添加自定义属性
console.log(arr.length); // 输出3,length只计算索引元素数量
console.log(arr[0]); // 输出10,通过数值索引访问元素
console.log(arr.customProp); // 输出额外属性
属性访问与遍历逻辑不同
对象访问属性可以用点符号或者方括号语法,遍历时常用for...in、Object.keys()等方法,而数组除了方括号访问索引元素外,还有专属的遍历方法如forEach、map等。for...in遍历数组时会同时遍历到自定义的非索引属性,这一点需要特别注意。
const arr = [1, 2, 3];
arr.extra = 'test';
// for...in会遍历到自定义属性
for (const key in arr) {
console.log(key); // 输出0,1,2,extra
}
// forEach只会遍历索引元素
arr.forEach((item, index) => {
console.log(index, item); // 只输出0 1,1 2,2 3
});
高级属性处理技巧
属性批量处理技巧
如果是需要给对象或者数组批量添加属性,可以用Object.assign方法,这个方法可以把多个源对象的属性复制到目标对象中,不会覆盖原有属性。
const targetObj = { a: 1 };
const sourceObj1 = { b: 2 };
const sourceObj2 = { c: 3, a: 4 }; // a属性会被忽略,因为targetObj已有a属性
Object.assign(targetObj, sourceObj1, sourceObj2);
console.log(targetObj); // 输出{a:1, b:2, c:3}
// 数组批量添加属性也可以用这个方法
const targetArr = [1, 2];
Object.assign(targetArr, { 2: 3, 3: 4, custom: 'val' });
console.log(targetArr); // 输出[1,2,3,4, custom:'val']
属性检测与判断技巧
判断某个属性是否存在时,要注意区分自身属性和原型链上的属性,常用的方法有hasOwnProperty、in操作符。hasOwnProperty只会检测自身属性,in操作符会检测自身和原型链上的属性。
const obj = { name: 'test' };
console.log(obj.hasOwnProperty('name')); // true
console.log(obj.hasOwnProperty('toString')); // false,toString是原型链上的属性
console.log('toString' in obj); // true
const arr = [1, 2];
console.log(arr.hasOwnProperty('length')); // true,length是数组自身内置属性
console.log(arr.hasOwnProperty('forEach')); // false,forEach是原型链上的方法
属性序列化处理技巧
对象或者数组转JSON字符串时,默认会序列化所有自身可枚举属性,如果要过滤某些属性,可以给对象添加toJSON方法,或者在JSON.stringify的第二个参数中指定需要保留的属性白名单。
const user = {
name: '李四',
password: '123456',
age: 30,
toJSON() {
// 过滤掉password属性
const { password, ...rest } = this;
return rest;
}
};
console.log(JSON.stringify(user)); // 输出{"name":"李四","age":30}
// 用第二个参数指定白名单
const arr = [10, 20, 30];
arr.extra = 'hide';
console.log(JSON.stringify(arr, ['0', '1', '2'])); // 输出[10,20,30],自定义属性不会被序列化
常见使用误区
很多开发者会误以为数组的length属性会统计所有属性,实际上length只会计算数值类型的索引元素数量,自定义的非数值键属性不会影响length的值。另外给数组添加大于当前length的索引元素时,中间的空位会被填充为undefined,遍历时需要注意空位的处理。
const arr = []; arr[5] = 'test'; console.log(arr.length); // 输出6 console.log(arr); // 输出[empty × 5, "test"] arr.forEach(item => console.log(item)); // 只会输出test,空位不会被遍历
JavaScriptarrayobjectproperty_processing修改时间:2026-06-15 01:21:35