对象(Object)
对象是 JavaScript 中最重要的数据类型,用来组织和存储数据。
1. 一句话概括主题
对象是键值对的集合,用来存储和组织相关的数据和功能,是 JavaScript 中组织代码的基本方式。
2. 它是什么
想象一个”学生档案”:
姓名:小明
年龄:18
班级:高三(1)班
成绩:{语文: 90, 数学: 95, 英语: 88}
这就是一个对象!每个”标签”(键)对应一个”值”。
在 JavaScript 中,对象就像这样的”档案袋”:
- 可以存储各种信息(属性)
- 可以存储功能(方法)
- 可以随时添加、修改、删除内容
简单理解:对象 = 一个”盒子”,里面可以放各种东西(数据和方法),每个东西都有个”标签”(属性名)。
3. 能解决什么问题 + 为什么重要
解决的问题
- 组织数据:把相关的数据放在一起,而不是用很多独立的变量
- 代码复用:可以创建多个相似的对象,共享结构
- 封装功能:把数据和操作数据的方法放在一起
- 模拟现实:用对象来模拟现实世界的事物
为什么重要
- JavaScript 的核心:JavaScript 中几乎所有东西都是对象
- 面向对象编程的基础:理解对象是学习面向对象编程的前提
- 实际开发必需:实际项目中大量使用对象来组织代码
- 理解其他概念:理解对象有助于理解类、原型、继承等概念
4. 核心知识点拆解
4.1 创建对象
对象字面量(最常用)
// 创建一个空对象
const person = {};
// 创建有属性的对象
const person = {
name: '小明',
age: 18,
city: '北京'
};使用 new Object()
const person = new Object();
person.name = '小明';
person.age = 18;使用 Object.create()
// 创建一个空对象(没有原型)
const person = Object.create(null);
person.name = '小明';4.2 访问对象属性
点号访问
const person = {
name: '小明',
age: 18
};
console.log(person.name); // '小明'
console.log(person.age); // 18方括号访问
const person = {
name: '小明',
age: 18
};
console.log(person['name']); // '小明'
console.log(person['age']); // 18
// 方括号可以访问动态属性名
const key = 'name';
console.log(person[key]); // '小明'4.3 对象方法
对象中可以存储函数,这些函数叫做”方法”:
const person = {
name: '小明',
age: 18,
// 方法:对象中的函数
greet: function() {
console.log(`你好,我是${this.name},今年${this.age}岁`);
},
// ES6 简写
introduce() {
console.log(`我是${this.name}`);
}
};
person.greet(); // 你好,我是小明,今年18岁
person.introduce(); // 我是小明4.4 添加和修改属性
const person = {
name: '小明'
};
// 添加新属性
person.age = 18;
person.city = '北京';
// 修改已有属性
person.name = '小红';
console.log(person); // { name: '小红', age: 18, city: '北京' }4.5 删除属性
const person = {
name: '小明',
age: 18,
city: '北京'
};
// 删除属性
delete person.city;
console.log(person); // { name: '小明', age: 18 }4.6 对象遍历
for…in 循环
const person = {
name: '小明',
age: 18,
city: '北京'
};
for (const key in person) {
console.log(`${key}: ${person[key]}`);
}
// 输出:
// name: 小明
// age: 18
// city: 北京Object.keys()
const person = {
name: '小明',
age: 18,
city: '北京'
};
const keys = Object.keys(person);
console.log(keys); // ['name', 'age', 'city']
keys.forEach(key => {
console.log(`${key}: ${person[key]}`);
});Object.values()
const values = Object.values(person);
console.log(values); // ['小明', 18, '北京']Object.entries()
const entries = Object.entries(person);
console.log(entries);
// [['name', '小明'], ['age', 18], ['city', '北京']]
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});4.7 对象合并
Object.assign()
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
// 合并对象(后面的会覆盖前面的)
const merged = Object.assign({}, obj1, obj2);
console.log(merged); // { a: 1, b: 3, c: 4 }展开运算符(ES6)
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
// 使用展开运算符合并
const merged = { ...obj1, ...obj2 };
console.log(merged); // { a: 1, b: 3, c: 4 }4.8 对象冻结和密封
Object.freeze() - 冻结对象
const person = {
name: '小明',
age: 18
};
Object.freeze(person);
person.name = '小红'; // 无效
person.city = '北京'; // 无效
delete person.age; // 无效
console.log(person); // { name: '小明', age: 18 }(没有变化)Object.seal() - 密封对象
const person = {
name: '小明',
age: 18
};
Object.seal(person);
person.name = '小红'; // 可以修改
person.city = '北京'; // 无效(不能添加)
delete person.age; // 无效(不能删除)
console.log(person); // { name: '小红', age: 18 }5. 示例代码(可运行 + 逐行注释)
示例 1:基础对象操作
// 创建一个学生对象
const student = {
// 基本属性
name: '小明',
age: 18,
grade: '高三',
// 嵌套对象
address: {
city: '北京',
district: '海淀区',
street: '中关村大街'
},
// 数组属性
subjects: ['语文', '数学', '英语'],
// 方法
introduce: function() {
console.log(`我是${this.name},今年${this.age}岁,读${this.grade}`);
},
// ES6 方法简写
getInfo() {
return {
name: this.name,
age: this.age,
grade: this.grade
};
}
};
// 访问属性
console.log(student.name); // 小明
console.log(student.address.city); // 北京
console.log(student.subjects[0]); // 语文
// 调用方法
student.introduce(); // 我是小明,今年18岁,读高三
console.log(student.getInfo()); // { name: '小明', age: 18, grade: '高三' }
// 修改属性
student.age = 19;
student.subjects.push('物理');
// 添加新属性
student.email = 'xiaoming@example.com';
console.log(student);示例 2:对象遍历和操作
const product = {
id: 1,
name: 'iPhone',
price: 5999,
category: '电子产品',
inStock: true
};
// 遍历对象的所有属性
console.log('=== 使用 for...in ===');
for (const key in product) {
console.log(`${key}: ${product[key]}`);
}
// 获取所有键
console.log('\n=== 所有键 ===');
const keys = Object.keys(product);
console.log(keys); // ['id', 'name', 'price', 'category', 'inStock']
// 获取所有值
console.log('\n=== 所有值 ===');
const values = Object.values(product);
console.log(values); // [1, 'iPhone', 5999, '电子产品', true]
// 获取所有键值对
console.log('\n=== 所有键值对 ===');
const entries = Object.entries(product);
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// 检查属性是否存在
console.log('\n=== 检查属性 ===');
console.log('name' in product); // true
console.log(product.hasOwnProperty('name')); // true
console.log('brand' in product); // false示例 3:对象合并和复制
// 对象合并
const defaultConfig = {
host: 'localhost',
port: 3000,
timeout: 5000
};
const userConfig = {
port: 8080,
debug: true
};
// 使用 Object.assign 合并
const config1 = Object.assign({}, defaultConfig, userConfig);
console.log(config1);
// { host: 'localhost', port: 8080, timeout: 5000, debug: true }
// 使用展开运算符合并
const config2 = { ...defaultConfig, ...userConfig };
console.log(config2);
// { host: 'localhost', port: 8080, timeout: 5000, debug: true }
// 对象浅拷贝
const original = {
name: '小明',
age: 18,
hobbies: ['读书', '运动']
};
// 浅拷贝(只拷贝第一层)
const copy1 = Object.assign({}, original);
const copy2 = { ...original };
copy1.name = '小红';
copy1.hobbies.push('音乐');
console.log('原始对象:', original);
// { name: '小明', age: 18, hobbies: ['读书', '运动', '音乐'] }
// 注意:hobbies 数组被修改了,因为浅拷贝只拷贝了引用
console.log('拷贝对象:', copy1);
// { name: '小红', age: 18, hobbies: ['读书', '运动', '音乐'] }6. 常见错误与踩坑
错误 1:访问不存在的属性
// ❌ 错误:访问不存在的属性返回 undefined
const person = { name: '小明' };
console.log(person.age); // undefined
// 如果继续使用 undefined 的属性会报错
console.log(person.age.toString()); // 报错!
// ✅ 正确:检查属性是否存在
if (person.age !== undefined) {
console.log(person.age.toString());
}
// 或者使用可选链(ES2020)
console.log(person.age?.toString()); // 安全,不会报错错误 2:this 指向问题
// ❌ 错误:this 指向错误
const person = {
name: '小明',
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
const greetFunc = person.greet;
greetFunc(); // undefined(this 指向全局对象或 undefined)
// ✅ 正确:使用箭头函数或 bind
const person = {
name: '小明',
greet: function() {
console.log(`你好,我是${this.name}`);
}
};
// 方法 1:使用 bind
const greetFunc = person.greet.bind(person);
greetFunc(); // 你好,我是小明
// 方法 2:直接调用
person.greet(); // 你好,我是小明错误 3:浅拷贝 vs 深拷贝
// ❌ 错误:浅拷贝,嵌套对象还是引用
const original = {
name: '小明',
address: {
city: '北京'
}
};
const copy = { ...original };
copy.address.city = '上海';
console.log(original.address.city); // '上海'(被修改了!)
// ✅ 正确:深拷贝
function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
const copy = deepCopy(original);
copy.address.city = '上海';
console.log(original.address.city); // '北京'(没有被修改)错误 4:修改 const 对象
// ❌ 误解:const 不能修改对象
const person = { name: '小明' };
person = { name: '小红' }; // 错误!不能重新赋值
// ✅ 正确:const 只是不能重新赋值,可以修改属性
const person = { name: '小明' };
person.name = '小红'; // 可以
person.age = 18; // 可以
delete person.name; // 可以
// 如果要完全不能修改,使用 Object.freeze()
const frozen = Object.freeze({ name: '小明' });
frozen.name = '小红'; // 无效7. 实际应用场景
场景 1:配置对象
// 应用配置
const appConfig = {
api: {
baseURL: 'https://api.example.com',
timeout: 5000,
retries: 3
},
ui: {
theme: 'dark',
language: 'zh-CN'
},
features: {
analytics: true,
logging: false
}
};
// 使用
const apiURL = appConfig.api.baseURL;场景 2:数据模型
// 用户数据模型
const user = {
id: 1,
username: 'xiaoming',
email: 'xiaoming@example.com',
profile: {
firstName: '明',
lastName: '小',
avatar: 'https://example.com/avatar.jpg'
},
preferences: {
theme: 'dark',
notifications: true
},
// 方法
getFullName() {
return `${this.profile.lastName}${this.profile.firstName}`;
},
updateEmail(newEmail) {
this.email = newEmail;
// 可以在这里添加保存逻辑
}
};
console.log(user.getFullName()); // 小明场景 3:函数参数对象
// 使用对象作为函数参数(更清晰)
function createUser(options) {
const {
name,
email,
age = 18, // 默认值
city = '北京'
} = options;
return {
name,
email,
age,
city,
createdAt: new Date()
};
}
// 使用
const user = createUser({
name: '小明',
email: 'xiaoming@example.com',
age: 20
});8. 给新手的练习题(可立即实践)
基础题:创建一个图书对象
要求:
- 创建一个
book对象 - 包含属性:书名、作者、价格、出版年份
- 包含方法:
getInfo()返回图书信息 - 添加一个
discount()方法,可以打折
进阶题:对象操作练习
要求:
- 创建一个学生对象数组
- 使用
Object.keys()、Object.values()、Object.entries()遍历 - 实现一个函数,合并多个学生的信息
- 实现一个函数,找出所有学生的平均年龄
9. 用更简单的话再总结一遍(方便复习)
对象是什么:
- 就是一个”盒子”,里面放各种东西
- 每个东西都有个”标签”(属性名)
核心要点:
- 用
{}创建对象 - 用
.或[]访问属性 - 对象中可以放数据(属性)和函数(方法)
- 可以用
for...in遍历对象 - 对象是引用类型,赋值是拷贝引用
记住:
- 对象 = 键值对的集合
- 用来组织和存储相关数据
- JavaScript 中几乎所有东西都是对象
10. 知识体系延伸 & 继续学习方向
相关知识点
继续学习方向
- 类语法:学习 ES6 的类,更现代的面向对象写法
- 原型链:理解对象的继承机制
- this 绑定:理解对象方法中的 this 指向
- 设计模式:学习如何使用对象实现设计模式
最后更新:2025