写给Pythoner的前端进阶指南(三):JavaScript面向对象编程-类、继承、多态和封装、this

面向对象编程(OOP)是现代编程语言中的核心概念之一,它有助于代码的组织和复用。在 Python 中,OOP 的特性(如类、继承、封装、多态)已经成为编程的基础,而在 JavaScript 中,这些概念的实现方式有所不同。如果你已经熟悉 Python 的面向对象编程,迁移到 JavaScript 可能会遇到一些新的语法和概念。在本篇文章中,我们将深入探讨 JavaScript 中的面向对象编程,并与 Python 进行对比,帮助你快速上手 JavaScript 的 OOP。

一、类与对象

1.1 如何定义类和实例

在 Python 中,你通过 class 关键字定义类,并使用构造函数(__init__)来初始化对象的属性。JavaScript 同样使用 class 关键字定义类,但构造函数的写法略有不同,通常是通过 constructor 来实现。

Python 中的类与对象:
python 复制代码
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        return f"Hello, my name is {self.name} and I am {self.age} years old."


# 创建对象
person1 = Person("Alice", 30)
print(person1.greet())  # 输出: Hello, my name is Alice and I am 30 years old.
JavaScript 中的类与对象:
javascript 复制代码
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    greet() {
        return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
    }
}

// 创建对象
const person1 = new Person("Alice", 30);
console.log(person1.greet());  // 输出: Hello, my name is Alice and I am 30 years old.

1.2 构造函数(constructor

在 Python 中,构造函数是 __init__,而在 JavaScript 中,它是一个名为 constructor 的特殊方法。JavaScript 的 constructor 是类的实例化过程中自动调用的。

javascript 复制代码
class Car {
    constructor(make, model, year) {
        this.make = make;
        this.model = model;
        this.year = year;
    }
}

const car1 = new Car("Toyota", "Corolla", 2020);
console.log(car1);  // 输出: Car { make: 'Toyota', model: 'Corolla', year: 2020 }

二、继承

2.1 继承(extends

继承是面向对象编程中的一个重要概念,它使得一个类可以继承另一个类的属性和方法。在 Python 中,继承通过在类定义时传入父类实现,而 JavaScript 则使用 extends 关键字来实现继承。

Python 中的继承:
python 复制代码
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return f"{self.name} makes a sound."

class Dog(Animal):
    def speak(self):
        return f"{self.name} barks."

# 创建 Dog 类的对象
dog = Dog("Buddy")
print(dog.speak())  # 输出: Buddy barks.
JavaScript 中的继承:
javascript 复制代码
class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        return `${this.name} makes a sound.`;
    }
}

class Dog extends Animal {
    speak() {
        return `${this.name} barks.`;
    }
}

const dog = new Dog("Buddy");
console.log(dog.speak());  // 输出: Buddy barks.

2.2 使用 super 关键字

在 JavaScript 中,可以使用 super 关键字调用父类的方法或构造函数。在继承中,super 用于调用父类的构造函数或覆盖父类的方法。

Python 中的 super() 调用父类方法:
python 复制代码
class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        return f"{self.name} makes a sound."

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)  # 调用父类的构造函数
        self.breed = breed

    def speak(self):
        return f"{self.name} barks."

dog = Dog("Buddy", "Golden Retriever")
print(dog.speak())  # 输出: Buddy barks.
JavaScript 中的 super 调用父类方法:
javascript 复制代码
class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        return `${this.name} makes a sound.`;
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);  // 调用父类的构造函数
        this.breed = breed;
    }

    speak() {
        return `${this.name} barks.`;
    }
}

const dog = new Dog("Buddy", "Golden Retriever");
console.log(dog.speak());  // 输出: Buddy barks.

三、多态与封装

3.1 封装:使用 gettersetter

封装是面向对象编程的一大特性,它允许我们控制对象的属性访问。在 JavaScript 中,我们可以通过 gettersetter 来实现封装。

Python 中的 gettersetter
python 复制代码
class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

person = Person("Alice", 30)
person.name = "Bob"  # 使用 setter 修改属性
print(person.name)   # 输出: Bob
JavaScript 中的 gettersetter
javascript 复制代码
class Person {
    constructor(name, age) {
        this._name = name;
        this._age = age;
    }

    get name() {
        return this._name;
    }

    set name(value) {
        this._name = value;
    }
}

const person = new Person("Alice", 30);
person.name = "Bob";  // 使用 setter 修改属性
console.log(person.name);  // 输出: Bob

3.2 多态:方法重写

在 OOP 中,多态是指不同的类可以以相同的接口实现不同的功能。在 JavaScript 中,你可以通过重写父类的方法来实现多态。

Python 中的多态(方法重写):
python 复制代码
class Animal:
    def speak(self):
        return "Animal makes a sound."

class Dog(Animal):
    def speak(self):
        return "Dog barks."

class Cat(Animal):
    def speak(self):
        return "Cat meows."

# 动态多态
animals = [Dog(), Cat()]
for animal in animals:
    print(animal.speak())  # 输出: Dog barks. Cat meows.
JavaScript 中的多态(方法重写):
javascript 复制代码
class Animal {
    speak() {
        return "Animal makes a sound.";
    }
}

class Dog extends Animal {
    speak() {
        return "Dog barks.";
    }
}

class Cat extends Animal {
    speak() {
        return "Cat meows.";
    }
}

// 动态多态
const animals = [new Dog(), new Cat()];
animals.forEach(animal => console.log(animal.speak()));  // 输出: Dog barks. Cat meows.

四、与 Python 的比较

4.1 self vs this

在 Python 中,类的方法通常有一个名为 self 的参数,表示当前实例;而在 JavaScript 中,类的方法则使用 this 来表示当前实例。它们本质上是相同的,只是命名不同。

Python 中的 self
python 复制代码
class Person:
    def __init__(self, name):
        self.name = name

    def greet(self):
        return f"Hello, my name is {self.name}."

person = Person("Alice")
print(person.greet())  # 输出: Hello, my name is Alice.
JavaScript 中的 this
javascript 复制代码
class Person {
    constructor(name) {
        this.name = name;
    }

    greet() {
        return `Hello, my name is ${this.name}.`;
    }
}

const person = new Person("Alice");
console.log(person.greet());  // 输出: Hello, my name is Alice.
``

`

### 4.2 其他区别

- JavaScript 是基于原型的继承,而 Python 是基于类的继承。虽然它们的继承机制不同,但基本的面向对象概念是相同的。
- JavaScript 使用 `constructor` 来初始化对象,而 Python 使用 `__init__`。

## 结语

通过本篇文章的介绍,你应该对 JavaScript 中的面向对象编程有了一个更深入的理解。虽然 JavaScript 和 Python 在语法和实现细节上有所不同,但它们的面向对象编程特性(如类、继承、封装、多态)非常相似。掌握这些概念后,你将能够更加轻松地在 JavaScript 中编写面向对象的代码。
相关推荐
ConardLi8 分钟前
Easy Dataset 已经突破 11.5K Star,这次又带来多项功能更新!
前端·javascript·后端
Blossom.1188 分钟前
把AI“编”进草垫:1KB决策树让宠物垫自己报「如厕记录」
java·人工智能·python·算法·决策树·机器学习·宠物
冴羽13 分钟前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript·性能优化
rising start15 分钟前
四、CSS选择器(续)和三大特性
前端·css
我先去打把游戏先20 分钟前
ESP32开发指南(基于IDF):连接AWS,乐鑫官方esp-aws-iot-master例程实验、跑通
开发语言·笔记·单片机·物联网·学习·云计算·aws
一 乐34 分钟前
高校后勤报修系统|物业管理|基于SprinBoot+vue的高校后勤报修系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·毕设
爱喝水的小周36 分钟前
《UniApp 页面配置文件pages.json》
前端·uni-app·json
极客数模40 分钟前
2025年(第六届)“大湾区杯”粤港澳金融数学建模竞赛准备!严格遵循要求,拿下大奖!
大数据·python·数学建模·金融·分类·图论·boosting
mapbar_front41 分钟前
React中useContext的基本使用和原理解析
前端·react.js
逻极1 小时前
Rust数据类型(上):标量类型全解析
开发语言·后端·rust