讲解
对象是键值对的集合,用花括号创建:const user = { name: '小明', age: 18 }。键(属性名)是字符串,值可以是任何类型,包括函数和其他对象。访问属性有两种语法:点语法 user.name 简洁,但要求属性名是合法标识符且写死在代码里;方括号语法 user['name'] 接受任意表达式,属性名存在变量里、或包含连字符空格等特殊字符时必须用它。
对象是动态的:随时可以 user.email = 'a@b.com' 添加属性,delete user.age 删除属性。判断属性是否存在用 'name' in user 或 Object.hasOwn(user, 'name')——注意 in 会沿原型链查找,Object.hasOwn 只看对象自身(老的 hasOwnProperty 方法在对象原型被改坏时不安全,ES2022 的 Object.hasOwn 是推荐替代)。读取不存在的属性得到 undefined 而不是报错,这既是便利也是坑。
ES6 给对象字面量带来了两个语法糖:属性简写 { name } 等价于 { name: name };计算属性名 { [key]: value } 让键可以来自变量。对象与数组一样是引用类型,按引用比较和传递;遍历对象最常用的方式不是 for...in,而是先转成数组:Object.keys(键数组)、Object.values(值数组)、Object.entries(键值对数组)。
示例
const user = { name: '小明', age: 18 };
console.log('点语法:', user.name);
console.log('方括号:', user['age']);
// 动态属性名必须用方括号
const field = 'name';
console.log('变量作键:', user[field]);
// 增、删、查
user.city = '北京';
delete user.age;
console.log('修改后:', user);
console.log('有 name:', Object.hasOwn(user, 'name'), '有 age:', Object.hasOwn(user, 'age'));
console.log('读取不存在的属性:', user.nothing); // undefined
// 属性简写与计算属性名
const name = '小红';
const key = 'score';
const record = { name, [key]: 99 };
console.log('简写与计算键:', record);
// 转成数组遍历
console.log('键:', Object.keys(record));
console.log('值:', Object.values(record));
for (const [k, v] of Object.entries(record)) {
console.log(k, '=', v);
}
常见坑
- 用点语法访问动态键:user.field 找的是字面属性 'field',不是变量 field 的值。变量作键必须 user[field]。
- 把「属性不存在」和「值为 undefined」混为一谈:{ a: undefined } 里 'a' in obj 是 true。严格区分时用 Object.hasOwn。
- 以为对象属性有固定顺序的怪癖:整数形态的键(如 '1'、'2')会被排在最前且按数值升序,其余键按插入序。依赖顺序的场景考虑 Map。
- 引用比较陷阱:{ a: 1 } === { a: 1 } 是 false。比较两个对象内容是否相等需要逐字段比较或序列化后比较。
小结
对象用点或方括号访问属性,可动态增删;Object.keys/values/entries 是遍历主力。下一节讲对象里的方法(函数属性)与复制、合并等操作。