【JS范式】一文读懂面向对象编程的根本
大家好,我是Ysh
JavaScript 是一种多范式语言,允许使用多种编程范式进行编程
,编程范式 指的是一组规则或准则,帮助你解决特定问题。而 面向对象编程 OOP
是一种通过对象的概念来组织代码的编程范式。
OOP的四大核心概念
面向对象编程(OOP)的四大核心概念是:
- 抽象
- 封装
- 继承
- 多态
可以说,掌握了这四大核心概念,也就明白了面向对象编程的根本。
抽象
抽象是指隐藏实现细节,将实现过程打包封装在一起,只提供一个简化的接口供你去调用。例如,当你使用一个函数时,不需要了解其内部实现,只需了解它的功能即可。这使代码更易于重用和维护。
示例:
function mainAPI(type){
if (type instanceof InitialLoad) { // 处理 InitialLoad 类型的逻辑
console.log("Initial Load API called");
} else if (type instanceof NavBar) {// 处理 NavBar 类型的逻辑
console.log("Nav Bar API called");
} else {
console.log("Default API called");
}
}
这个例子没有进行很好的抽象化,因为每新增一个 API 类型都需要新增一个 if 块和自定义代码,而不是调用简化的接口。
更好的抽象方式是:
// 定义 HTTP 方法常量
const HTTPMethod = {
GET: 'GET',
POST: 'POST',
PUT: 'PUT',
DELETE: 'DELETE'
};
// 通用的 API 处理函数
function handleRequest(method, url) {
switch (method) {
case HTTPMethod.GET:
console.log(`GET request to ${url}`);
break;
case HTTPMethod.POST:
console.log(`POST request to ${url}`);
break;
case HTTPMethod.PUT:
console.log(`PUT request to ${url}`);
break;
case HTTPMethod.DELETE:
console.log(`DELETE request to ${url}`);
break;
default:
console.log(`Unknown method: ${method}`);
}
}
// 抽象的 mainAPI 函数
function mainAPI(url, method) {
// 调用通用的 API 处理函数
handleRequest(method, url);
}
// 测试调用
mainAPI('www.web-ysh.com', HTTPMethod.GET); // GET request to www.web-ysh.com
mainAPI('www.web-ysh.com', HTTPMethod.POST); // POST request to www.web-ysh.com
mainAPI('www.web-ysh.com', HTTPMethod.PUT); // PUT request to www.web-ysh.com
mainAPI('www.web-ysh.com', HTTPMethod.DELETE); // DELETE request to www.web-ysh.com
mainAPI('www.web-ysh.com', 'PATCH'); // Unknown method: PATCH
在这个例子中,只需传递 URL 和 HTTP 方法,内部细节已被抽象化,提高了代码的重用性和可维护性。
封装
封装是指将代码的某些部分封闭,使其成为私有,仅允许必要的访问。通过封装,可以控制对象的状态,并限制外部对其直接修改。
示例:
// 创建一个模块,用于封装数据和方法
const DogModule = (function () {
// 私有数据和方法
let breed = "Dalmatian";
const play = function () {
console.log("Playing...");
};
// 公有数据和方法
return {
name: "Rex",
makeNoise: function () {
console.log("Bark bark!");
},
getBreed: function () {
return breed;
},
setBreed: function (newBreed) {
breed = newBreed;
},
play: play // 暴露私有的 play 方法
};
})();
// 使用封装模块
console.log(DogModule.name); // Rex
DogModule.makeNoise(); // Bark bark!
console.log(DogModule.getBreed()); // Dalmatian
DogModule.setBreed("Labrador");
console.log(DogModule.getBreed()); // Labrador
DogModule.play(); // Playing...
在这个例子中,play
和 breed
是私有的,makeNoise
和 name
是公有的。通过这种方式,封装了部分细节,只暴露必要的部分。
继承
继承允许一个对象获取另一个对象的属性和方法,在 JavaScript 中,通过原型继承实现。继承的主要好处是可重用性,允许共享大部分功能,同时添加或重写部分功能。
示例:
// 定义基类 Animal
class Animal {
constructor(name) {
this.name = name;
this.legs = 4;
}
makeNoise() {
console.log("Base noise");
}
}
// 定义子类 Dog,继承自 Animal
class Dog extends Animal {
constructor(name) {
super(name); // 调用父类的构造函数
}
makeNoise() {
console.log("Woof woof");
}
}
// 测试继承
const genericAnimal = new Animal("Generic Animal");
genericAnimal.makeNoise(); // Base noise
const dog = new Dog("Rex");
dog.makeNoise(); // Woof woof
console.log(dog.legs); // 4
在这个例子中,Dog
继承了 Animal
的属性和方法,并重写了 makeNoise
方法。
多态
多态允许同一继承链中的对象以不同的方式实现相同的方法。通过多态,可以共享行为,并允许对象根据需要自定义实现。
示例:
// 定义基类 Animal
class Animal {
constructor(name) {
this.name = name;
}
makeNoise() {
console.log("Base noise");
}
}
// 定义子类 Dog,继承自 Animal
class Dog extends Animal {
makeNoise() {
console.log("Woof woof");
}
}
// 定义子类 Cat,继承自 Animal
class Cat extends Animal {
makeNoise() {
console.log("Meow");
}
}
// 定义通用的噪音制造器函数
function makeAnimalNoise(animal) {
animal.makeNoise();
}
// 测试多态
const dog = new Dog("Rex");
const cat = new Cat("Whiskers");
makeAnimalNoise(dog); // Woof woof
makeAnimalNoise(cat); // Meow
Dog
扩展自 Animal
,可以使用默认的 legs
属性,但也可以重写 makeNoise
方法。
总结
面向对象编程(OOP)是 JavaScript 中一种强大的编程范式,通过它可以提高代码的可维护性、可重用性和可扩展性。理解和掌握 OOP 的四大核心概念:抽象、封装、继承、多态,理解这四大核心就掌握了面向对象编程。
-
抽象:通过隐藏实现细节,只提供一个简化的接口,使代码更易于理解和重用。
-
封装:将代码的某些部分封闭,控制对象的状态,限制外部对其的直接修改。
-
继承:通过原型链机制,让一个对象获取另一个对象的属性和方法,实现代码的重用。
-
多态:允许同一继承链中的对象以不同的方式实现相同的方法,实现共享行为和自定义实现。
转载自:https://juejin.cn/post/7368302136688361482