Skip to content

Python vs. JavaScript: 面向对象编程 (OOP) 对比指南

面向对象编程(OOP)是一种核心的编程范式,它使用"对象"来设计软件。本文档旨在深入对比 Python 和 JavaScript 在面向对象编程方面的核心理念、语法结构和实现差异。


核心哲学与概念对比

  • Python: 经典、明确的类模型 Python 从一开始就被设计为一门清晰、传统的类 기반 (Class-based) 面向对象语言。它的 OOP 模型直接、明确,遵循其"明确优于隐晦"的核心哲学。

  • JavaScript: 从原型到类的演进 JavaScript 的根基是原型 기반 (Prototype-based) 继承模型,这是一种更灵活但也更不寻常的继承方式。ES6 引入的 class 关键字主要是对原型继承的"语法糖",它让代码看起来更像传统的 OOP,但其底层机制与 Python 等语言完全不同。

特性 (Feature)PythonJavaScript (ES6+)
类定义class MyClass:class MyClass { ... }
构造函数__init__(self, ...)constructor(...)
实例引用self (必须作为方法的第一个参数显式传递)this (隐式存在,其值由调用方式决定)
实例化my_obj = MyClass()const myObj = new MyClass() (必须使用 new)
继承class Child(Parent):class Child extends Parent { ... }
调用父类方法super().method()super().__init__()super.method()super()
私有成员约定: _ (保护), __ (伪私有,名称改写)语言级支持: # (真私有字段/方法)
继承模型支持多重继承只支持单一继承 (通过 Mixin 模式模拟多重)

1. 类与对象的创建 (Instantiation)

Python

python
class Dog:
    # 构造函数
    def __init__(self, name, breed):
        self.name = name  # 实例属性
        self.breed = breed

    # 实例方法,self 是必需的
    def bark(self):
        return f"{self.name} says woof!"

# 实例化
my_dog = Dog("Rex", "German Shepherd")
print(my_dog.bark()) # -> "Rex says woof!"

JavaScript

javascript
class Dog {
  // 构造函数
  constructor(name, breed) {
    this.name = name; // 实例属性
    this.breed = breed;
  }

  // 实例方法,this 是隐式的
  bark() {
    return `${this.name} says woof!`;
  }
}

// 实例化,new 是必需的
const myDog = new Dog("Rex", "German Shepherd");
console.log(myDog.bark()); // -> "Rex says woof!"

核心对比:

  • 构造函数: Python 使用 __init__,JS 使用 constructor
  • 实例引用: Python 必须显式传递 self,而 JS 的 this 是隐式可用的。
  • 实例化: JS 必须使用 new 关键字,而 Python 不需要。

2. 属性与方法

Python

Python 明确区分实例属性和类属性。

python
class Car:
    # 类属性,被所有实例共享
    wheels = 4

    def __init__(self, color):
        # 实例属性
        self.color = color

car1 = Car("red")
car2 = Car("blue")

print(car1.wheels) # -> 4
print(Car.wheels)  # -> 4

JavaScript

传统上所有属性都在 constructor 中定义,但现代 JS 也支持公共类字段,使其与 Python 更相似。

javascript
class Car {
  // 公共类字段,被所有实例共享 (类似 Python 的类属性)
  wheels = 4;

  constructor(color) {
    // 实例属性
    this.color = color;
  }
}

const car1 = new Car("red");
const car2 = new Car("blue");

console.log(car1.wheels); // -> 4
// console.log(Car.wheels); // ES2022 后支持 static public fields

3. 继承 (Inheritance)

Python

支持多重继承,语法简洁。

python
class Animal:
    def __init__(self, name):
        self.name = name
    def speak(self):
        raise NotImplementedError

class Dog(Animal): # 继承自 Animal
    def speak(self):
        return "Woof!"

# 多重继承
class Flyer:
    def fly(self):
        return "I can fly!"

class FlyingDog(Dog, Flyer): # 同时继承 Dog 和 Flyer
    pass

my_flying_dog = FlyingDog("Sparky")
print(my_flying_dog.speak()) # -> "Woof!"
print(my_flying_dog.fly())   # -> "I can fly!"

JavaScript

只支持单一继承,使用 extendssuper 关键字。

javascript
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    throw new Error("speak() must be implemented by subclasses");
  }
}

class Dog extends Animal { // 继承自 Animal
  // 如果子类有构造函数,必须先调用 super()
  constructor(name, breed) {
    super(name); // 调用父类的构造函数
    this.breed = breed;
  }
  speak() {
    return "Woof!";
  }
}

const myDog = new Dog("Buddy", "Golden Retriever");
console.log(myDog.speak()); // -> "Woof!"

4. 封装与私有性

这是两者之间一个非常关键的区别。

Python: 约定式私有

Python 没有真正的私有性,而是依赖命名约定。

  • _protected (单下划线): 告诉其他开发者这是一个内部属性,是"受保护的",但不应从外部访问。这只是一个君子协定。
  • __private (双下划线): 触发名称改写 (Name Mangling)。Python 解释器会将其重命名为 _ClassName__private,使其难以从外部访问,但仍然不是真正的私有。
python
class MyClass:
    def __init__(self):
        self._protected_var = 1
        self.__private_var = 2
    
    def get_private(self):
        return self.__private_var

obj = MyClass()
print(obj._protected_var) # -> 1 (可以访问,但不推荐)
# print(obj.__private_var)  # -> AttributeError
print(obj._MyClass__private_var) # -> 2 (仍然可以访问)

JavaScript: 真私有

现代 JavaScript 使用 # 前缀来创建真正的私有字段和方法,外部代码完全无法访问。

javascript
class MyClass {
  #privateVar = 2; // 私有字段

  constructor() {
    this.publicVar = 1;
  }

  getPrivate() {
    return this.#privateVar; // 内部可以访问
  }
}

const obj = new MyClass();
console.log(obj.publicVar); // -> 1
console.log(obj.getPrivate()); // -> 2
// console.log(obj.#privateVar); // -> SyntaxError

5. 底层模型:类 vs. 原型

  • Python 是一个纯粹的类 기반语言。类是创建对象的蓝图,对象是类的实例。
  • JavaScriptclass 语法是建立在原型继承模型之上的语法糖。每个对象都有一个指向其"原型"对象的内部链接,它从原型对象继承属性和方法。理解这一点有助于解释 this 的动态行为和 JS 对象模型的许多其他特性。