对象(Object)

对象是 JavaScript 中最重要的数据类型,用来组织和存储数据。


1. 一句话概括主题

对象是键值对的集合,用来存储和组织相关的数据和功能,是 JavaScript 中组织代码的基本方式。


2. 它是什么

想象一个”学生档案”:

姓名:小明
年龄:18
班级:高三(1)班
成绩:{语文: 90, 数学: 95, 英语: 88}

这就是一个对象!每个”标签”(键)对应一个”值”。

在 JavaScript 中,对象就像这样的”档案袋”:

  • 可以存储各种信息(属性)
  • 可以存储功能(方法)
  • 可以随时添加、修改、删除内容

简单理解:对象 = 一个”盒子”,里面可以放各种东西(数据和方法),每个东西都有个”标签”(属性名)。


3. 能解决什么问题 + 为什么重要

解决的问题

  1. 组织数据:把相关的数据放在一起,而不是用很多独立的变量
  2. 代码复用:可以创建多个相似的对象,共享结构
  3. 封装功能:把数据和操作数据的方法放在一起
  4. 模拟现实:用对象来模拟现实世界的事物

为什么重要

  • 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. 给新手的练习题(可立即实践)

基础题:创建一个图书对象

要求

  1. 创建一个 book 对象
  2. 包含属性:书名、作者、价格、出版年份
  3. 包含方法:getInfo() 返回图书信息
  4. 添加一个 discount() 方法,可以打折

进阶题:对象操作练习

要求

  1. 创建一个学生对象数组
  2. 使用 Object.keys()Object.values()Object.entries() 遍历
  3. 实现一个函数,合并多个学生的信息
  4. 实现一个函数,找出所有学生的平均年龄

9. 用更简单的话再总结一遍(方便复习)

对象是什么

  • 就是一个”盒子”,里面放各种东西
  • 每个东西都有个”标签”(属性名)

核心要点

  1. {} 创建对象
  2. .[] 访问属性
  3. 对象中可以放数据(属性)和函数(方法)
  4. 可以用 for...in 遍历对象
  5. 对象是引用类型,赋值是拷贝引用

记住

  • 对象 = 键值对的集合
  • 用来组织和存储相关数据
  • JavaScript 中几乎所有东西都是对象

10. 知识体系延伸 & 继续学习方向

相关知识点

继续学习方向

  1. 类语法:学习 ES6 的类,更现代的面向对象写法
  2. 原型链:理解对象的继承机制
  3. this 绑定:理解对象方法中的 this 指向
  4. 设计模式:学习如何使用对象实现设计模式

最后更新:2025

javascript 对象 面向对象 前端基础