C11. 面向对象初步
1.1. ⭐ 面向对象简化面向过程的代码组织
当代码规模变大时,函数和变量散落在各处,如同“面条代码”。面向对象(OOP)通过对象将数据和行为封装在一起,让代码更易维护。
示例对比:
javascript
// 面向过程写法(散落的变量和函数)
let studentName = "Alice";
let studentAge = 16;
function sayHello() {
console.log(`你好,我是${studentName}`);
}
function celebrateBirthday() {
studentAge++;
}
javascript
// 面向对象写法(对象封装)
const student = {
name: "Alice",
age: 16,
sayHello: function() {
console.log(`你好,我是${this.name}`);
},
celebrateBirthday: function() {
this.age++;
}
};
封装优势
- 数据和方法绑定在一起
- 通过
this
关键字访问内部属性 - 外界无法直接修改内部状态(可添加 getter/setter)
1.2. ⭐ 抽象是面向对象的本质
面向对象的核心是抽象,即提炼共性、隐藏细节。通过**类(Class)**描述对象的蓝图。
javascript
// 定义类
class Animal {
constructor(name) {
this.name = name;
}
// 抽象方法(子类必须实现)
speak() {
throw new Error("子类需实现此方法");
}
}
// 继承与具体化
class Dog extends Animal {
speak() {
return `${this.name} 汪汪叫`;
}
}
const dog = new Dog("旺财");
console.log(dog.speak()); // 旺财 汪汪叫
抽象的三个层次:
- 封装:将数据和方法包装在对象中
- 继承:通过
extends
继承已有类的特性 - 多态:子类重写父类方法实现不同行为
1.3. 🌟 JavaScript 使用原型链实现面向对象
JavaScript 的面向对象机制与传统 OOP 不同,它通过**原型链(Prototype Chain)**实现继承。
核心概念:
- 原型对象:每个函数都有一个
prototype
属性指向原型对象 - 实例关联:对象通过
__proto__
指向构造函数的原型 - 链式查找:当访问属性时,会沿着原型链向上查找
javascript
// 创建对象
function Person(name) {
this.name = name;
}
// 原型方法
Person.prototype.sayHello = function() {
return `你好,我是${this.name}`;
};
const p = new Person("Bob");
console.log(p.sayHello()); // 你好,我是Bob
console.log(p.__proto__ === Person.prototype); // true
注意事项
- 原型方法被所有实例共享
- 实例属性直接定义在
this
上 - 真正的继承需要手动设置
__proto__
知识回顾
- 面向对象三大特性:
- 封装:通过对象将数据和方法绑定
- 继承:通过
extends
继承父类特性 - 多态:子类重写父类方法
- JavaScript 特色:
- 通过构造函数 + 原型链实现继承
new
关键字创建实例- 原型链形成属性查找链
- 关键语法:
class
/constructor
extends
/super
prototype
/__proto__
课后练习
(单选)以下哪个是正确创建对象的方式?
- A.
const obj = {name:"Tom"}
- B.
function Person(){}; new Person()
- C.
class Animal; new Animal()
- D. 以上都是
- A.
(填空)通过______关键字实现类继承,通过______访问原型方法。
(代码纠错)修复以下继承代码:
javascriptclass Animal { speak() { return "Animal"; } } class Cat extends Animal { speak() { return super.speak() + "喵"; } } const cat = new Cat(); console.log(cat.speak());
(操作题)用原型链实现一个 Shape 类,要求:
- 包含
getType()
方法返回 "形状" - 子类 Circle 继承并重写该方法返回 "圆形"
- 包含