Javascript 零基础教程

JavaScript 对象创建

JavaScript 作为一门多功能的编程语言,允许我们在代码中模拟复杂的现实世界实体。

虽然我们已经学习了基本的数据类型(如数字、字符串和布尔值),甚至是像数组这样的集合,但在表示具有多个不同特征和行为的事物时,仅靠这些往往是不够的。

这就是 对象 (Objects) 派上用场的地方。对象是基本的构建块,允许我们将相关的数据和功能组合成一个单一的、紧密联系的单元,就像现实世界中的物品拥有特定的属性和它可以执行的动作一样。

理解如何创建这些对象、定义它们的属性 (Properties) 以及分配行为 (Methods,即方法),对于编写更有条理、更强大且更易读的 JavaScript 代码至关重要。

1. 理解对象:属性与方法

在 JavaScript 中,对象是一个独立的实体,拥有属性和类型。你可以把对象想象成一个容器,它容纳着与同一个概念相关的各种信息片段和特定动作。

这个概念可以是一个人、一辆车、一本书,甚至是一个应用程序的配置设置。

2. 使用对象字面量创建对象

在 JavaScript 中创建对象最常用、最直接的方法是使用 对象字面量 (Object Literal)。对象字面量是被花括号 {} 包围的一组逗号分隔的“名称-值”对(即属性)。

当你使用 constlet 声明一个对象时,你本质上是在内存中创建了对该对象的一个引用。

// 一个代表“人”的基本对象字面量
const person = {
  // 属性写在这里
};

// 一个代表“产品”的基本对象字面量
let product = {
  // 属性写在这里
};

这种语法简单、直接,被广泛用于创建单个对象实例。

3. 定义属性 (Properties)

属性 是对象的特征或特性。它们是“键-值”对,其中 键 (Key)(也称为属性名)通常是一个描述该数据的字符串,而 值 (Value) 是实际的数据。

值可以是我们要介绍过的任何 JavaScript 数据类型:数字、字符串、布尔值、数组,甚至是另一个对象!

3.1 属性的语法

propertyName: value

propertyName(属性名)通常是一个标识符(如 firstName, age),但如果它包含空格或特殊字符,则必须用引号括起来(例如 "first name")。为了简单和符合最佳实践,通常建议使用不带空格或特殊字符的标识符友好型名称。

3.2 带有属性的对象示例

让我们想象一下,我们想表示一个学生。一个学生有一个名字、一个 ID、一个成绩,也许还有一个他们注册课程的列表。

const student = {
  firstName: "Alice",     // 字符串属性
  lastName: "Smith",      // 字符串属性
  studentId: 101,         // 数字属性
  isEnrolled: true,       // 布尔值属性
  grade: 92.5,            // 数字属性
  courses: ["数学", "科学", "历史"], // 数组属性
  address: {              // 对象属性 (嵌套对象)
    street: "主街 123 号",
    city: "任意城",
    zipCode: "12345"
  }
};

console.log(student);

/*
输出:
{
  firstName: 'Alice',
  lastName: 'Smith',
  studentId: 101,
  isEnrolled: true,
  grade: 92.5,
  courses: [ '数学', '科学', '历史' ],
  address: { street: '主街 123 号', city: '任意城', zipCode: '12345' }
}
*/

在这个 student 对象中:

  • firstNamelastNamestudentIdisEnrolledgradecourses 都是属性。
  • 它们的值是不同的数据类型(字符串、数字、布尔值、数组)。
  • address 也是一个属性,但它的值是 另一个对象。这演示了对象如何嵌套以表示更复杂的关系。

另一个例子:表示图书馆里的一本

const book = {
  title: "JavaScript 奇遇记",
  author: "J.S. Developer",
  publicationYear: 2023,
  pageCount: 450,
  isAvailable: true,
  genres: ["编程", "教育"]
};

console.log(book);

/*
输出:
{
  title: 'JavaScript 奇遇记',
  author: 'J.S. Developer',
  publicationYear: 2023,
  pageCount: 450,
  isAvailable: true,
  genres: [ '编程', '教育' ]
}
*/

在这里,titleauthorpublicationYearpageCountisAvailablegenres 都是定义 book 对象不同方面的属性。

4. 定义方法 (Methods)

如果说属性描述了一个对象是什么,那么方法则描述了一个对象能做什么

方法 仅仅是存储为对象属性的函数。就像普通函数(第 5 模块)一样,方法可以执行动作、接收参数并返回值。关键的区别在于它们与一个对象内在通过关联。

4.1 方法的语法

你可以使用函数表达式作为属性值来定义方法:

methodName: function(parameters) {
  // 方法体
}

或者,使用更现代、更简洁的方法语法(ES6+),这通常是首选:

methodName(parameters) {
  // 方法体
}

4.2 带有方法的对象示例

让我们增强我们的 student 对象,添加一个让他们自我介绍的方法。

const student = {
  firstName: "Alice",
  lastName: "Smith",
  studentId: 101,
  isEnrolled: true,
  grade: 92.5,
  courses: ["数学", "科学", "历史"],
  
  // 一个让学生自我介绍的方法
  introduce: function() {
    console.log("你好,我的名字是 " + this.firstName + " " + this.lastName + "。");
    // 注意:`this` 关键字将在后面的课程中详细解释。
    // 现在,你只需要理解 `this.firstName` 指的是 *这个* 对象的 `firstName` 属性。
  }
};

// 要调用方法,使用点符号后跟括号
student.introduce(); // 输出: 你好,我的名字是 Alice Smith。

在这个例子中,introducestudent 对象的一个方法。当被调用时,它使用对象自己的属性执行一个动作(向控制台打印一条消息)。

让我们再看一个例子,一个执行算术运算的 计算器 (calculator) 对象。

const calculator = {
  // 属性 (可选,但可以用来存储状态,例如当前结果)
  currentResult: 0,

  // 两个数相加的方法
  add: function(num1, num2) {
    this.currentResult = num1 + num2;
    console.log("加法结果: " + this.currentResult);
    return this.currentResult;
  },

  // 两个数相减的方法 (使用简洁方法语法)
  subtract(num1, num2) {
    this.currentResult = num1 - num2;
    console.log("减法结果: " + this.currentResult);
    return this.currentResult;
  },

  // 两个数相乘的方法
  multiply: (num1, num2) => { // 方法也可以使用箭头函数语法
    // 注意:在箭头函数中使用 `this` 需要小心,我们稍后会讨论
    // 这里为了演示暂且这样写,但在实际的对象方法中推荐前两种写法以确保 `this` 指向正确
    console.log("乘法逻辑演示"); 
  },

  // 获取当前存储结果的方法
  getResult() {
    return this.currentResult;
  }
};

// 调用方法
calculator.add(5, 3);      // 输出: 加法结果: 8
calculator.subtract(10, 4); // 输出: 减法结果: 6
console.log("当前结果: " + calculator.getResult()); // 输出: 当前结果: 6

在这里,addsubtractgetResultcalculator 对象的方法。它们封装了不同算术运算的逻辑,甚至可以与对象的内部状态(如 currentResult)进行交互。

示例中使用的 this 关键字(例如 this.firstName, this.currentResult)指的是对象本身。当一个方法被调用时,该方法内部的 this 指向“拥有”该方法的对象。这允许方法访问和修改对象的属性。我们将在未来的课程中深入探讨 this 关键字,但现在,只需知道它允许方法与其所属对象的数据进行交互即可。

5. 实战示例与演示

让我们把属性和方法结合起来,构建一个更全面的对象,代表一辆 车 (Car)

// 定义一个包含属性和方法的 Car 对象
const myCar = {
  make: "Toyota",
  model: "Camry",
  year: 2020,
  color: "银色",
  mileage: 50000,
  isRunning: false, // 初始状态

  // 启动汽车的方法
  start: function() {
    if (!this.isRunning) {
      this.isRunning = true;
      console.log(`${this.make} ${this.model} 现在正在运行。`);
    } else {
      console.log(`${this.make} ${this.model} 已经在运行了。`);
    }
  },

  // 停止汽车的方法
  stop() { // 使用简洁方法语法
    if (this.isRunning) {
      this.isRunning = false;
      console.log(`${this.make} ${this.model} 已停止。`);
    } else {
      console.log(`${this.make} ${this.model} 已经是停止状态。`);
    }
  },

  // 驾驶汽车的方法,增加里程数
  drive(distance) {
    if (this.isRunning) {
      this.mileage += distance;
      console.log(`行驶了 ${distance} 英里。总里程: ${this.mileage}`);
    } else {
      console.log(`无法驾驶。${this.make} ${this.model} 没有运行。`);
    }
  },

  // 获取汽车信息的方法
  getInfo: function() {
    return `这是一辆 ${this.year} 年的 ${this.make} ${this.model},颜色为${this.color},里程 ${this.mileage} 英里。它当前处于${this.isRunning ? '运行' : '停止'}状态。`;
  }
};

console.log("--- 初始汽车状态 ---");
console.log(myCar.getInfo()); 
// 输出: 这是一辆 2020 年的 Toyota Camry,颜色为银色,里程 50000 英里。它当前处于停止状态。

console.log("\n--- 启动汽车 ---");
myCar.start();              // 输出: Toyota Camry 现在正在运行。
console.log(myCar.getInfo()); 
// 输出: 这是一辆 2020 年的 Toyota Camry,颜色为银色,里程 50000 英里。它当前处于运行状态。

console.log("\n--- 尝试再次启动 ---");
myCar.start();              // 输出: Toyota Camry 已经在运行了。

console.log("\n--- 驾驶汽车 ---");
myCar.drive(100);           // 输出: 行驶了 100 英里。总里程: 50100
myCar.drive(50);            // 输出: 行驶了 50 英里。总里程: 50150
console.log(myCar.getInfo()); 
// 输出: 这是一辆 2020 年的 Toyota Camry,颜色为银色,里程 50150 英里。它当前处于运行状态。

console.log("\n--- 停止汽车 ---");
myCar.stop();               // 输出: Toyota Camry 已停止。
console.log(myCar.getInfo()); 
// 输出: 这是一辆 2020 年的 Toyota Camry,颜色为银色,里程 50150 英里。它当前处于停止状态。

console.log("\n--- 尝试驾驶已停止的汽车 ---");
myCar.drive(20);            // 输出: 无法驾驶。Toyota Camry 没有运行。

这个综合性的 myCar 对象完美地展示了属性(如 make, model, mileage)如何保存数据,而方法(start, stop, drive, getInfo)如何封装与该数据相关的动作和逻辑。这些方法修改了对象的属性(isRunning, mileage)并对其当前状态做出反应。