Object-Oriented Programming in JavaScript
In this lesson, we’ll explore how JavaScript implements object-oriented programming (OOP) concepts and compare it with Python’s approach. While both languages support OOP, JavaScript’s implementation has some unique characteristics that set it apart from Python’s class-based system.
Prototypal Inheritance vs Class-based Inheritance
JavaScript traditionally uses prototypal inheritance, which is different from Python’s class-based inheritance. In prototypal inheritance, objects inherit directly from other objects. However, to make things more familiar for developers coming from class-based languages, JavaScript introduced the class
syntax in ES6.
// JavaScript
// Traditional prototypal approach
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function () {
console.log(`${this.name} makes a sound.`);
};
// ES6 class syntax (syntactic sugar over prototypes)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
# Python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} makes a sound.")
While the ES6 class
syntax looks similar to Python, it’s important to remember that under the hood, JavaScript is still using prototypal inheritance.
Constructor Functions and the new
Keyword
In JavaScript, constructor functions are used to create objects. These are similar to Python’s __init__
method, but with some key differences:
// JavaScript
function Dog(name, breed) {
this.name = name;
this.breed = breed;
}
const myDog = new Dog('Buddy', 'Golden Retriever');
The new
keyword in JavaScript is crucial here. It creates a new object, sets this
to refer to that object within the constructor function, and returns the object. In Python, object creation is handled implicitly when you call the class.
Inheritance with extends
and super
JavaScript’s ES6 classes support inheritance using the extends
keyword, similar to Python:
// JavaScript
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() {
console.log(`${this.name} barks.`);
}
}
# Python
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
def speak(self):
print(f"{self.name} barks.")
The super
keyword in JavaScript, like in Python, is used to call methods on the parent class.
Static Methods and Properties
Both JavaScript and Python support static methods and properties, which belong to the class itself rather than instances of the class:
// JavaScript
class MathOperations {
static PI = 3.14159;
static square(x) {
return x * x;
}
}
console.log(MathOperations.PI);
console.log(MathOperations.square(4));
# Python
class MathOperations:
PI = 3.14159
@staticmethod
def square(x):
return x * x
print(MathOperations.PI)
print(MathOperations.square(4))
Encapsulation and Privacy in JavaScript
JavaScript traditionally doesn’t have built-in privacy mechanisms like Python’s convention of using underscores for private attributes. However, there are ways to achieve privacy:
// JavaScript
class BankAccount {
#balance = 0; // Private field (recent addition to JavaScript)
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(100);
console.log(account.getBalance()); // 100
console.log(account.#balance); // SyntaxError: Private field '#balance' must be declared in an enclosing class
The #
prefix for private fields is a recent addition to JavaScript and may not be supported in all environments yet. Before this, developers used closures or symbols to achieve privacy.
Conclusion
While JavaScript’s object-oriented programming model has its roots in prototypal inheritance, the introduction of the class
syntax has made it more accessible to developers coming from class-based languages like Python. Though the two languages differ in syntax and terminology, both implement inheritance through runtime delegation along a chain—whether it’s Python’s class hierarchy or JavaScript’s prototype chain. Understanding these similarities and the subtle differences will help you write more effective and idiomatic JavaScript code.
In the next lesson, we’ll explore functional programming features in JavaScript, comparing them with Python’s approach to functional programming. We’ll look at how JavaScript’s first-class functions, higher-order functions, and unique features like the this
keyword present both challenges and opportunities for Python developers.