Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Kế thừa (Inheritance) trong JavaScript

Khái niệm

JavaScript sử dụng Prototypal Inheritance (kế thừa dựa trên nguyên mẫu) thay vì Class-based inheritance như Java/C++. Đối tượng kế thừa từ đối tượng khác thông qua chuỗi prototype (__proto__).

Cách thực hiện (ES5 - Constructor Function)

<!DOCTYPE html>
<html lang="vi">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JS Inheritance</title>
    <style>
        body { font-family: 'Segoe UI', sans-serif; padding: 20px; }
        .result { font-size: 16px; color: #6a1b9a; font-weight: 500; margin: 20px 0; padding: 15px; background: #f3e5f5; border-radius: 4px; min-height: 100px; white-space: pre-wrap; }
        button { padding: 10px 20px; background: #1976d2; color: white; border: none; border-radius: 4px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>Kế thừa trong JavaScript (Prototype)</h1>
    <div class="result" id="result"></div>
    <button id="btn">TẠO ĐỐI TƯỢNG & GỌI PHƯƠNG THỨC KẾ THỪA</button>
    <h3>Nhấn nút để tạo person1, person2 và gọi welcome() kế thừa</h3>

    <script>
        const btnEle = document.getElementById('btn');
        const resEle = document.getElementById('result');

        // Constructor function (Parent)
        function Person(name, age, city) {
            this.name = name;
            this.age = age;
            this.city = city;
        }

        // Thêm method vào prototype - CHIA SẺ cho tất cả instance
        Person.prototype.welcome = function() {
            resEle.textContent += `Welcome ${this.name} age: ${this.age} city: ${this.city}\n`;
        };

        btnEle.addEventListener('click', () => {
            resEle.textContent = '';
            
            // Tạo instance
            const person1 = new Person('Rohan', 22, 'Delhi');
            person1.welcome(); // Gọi method từ prototype
            
            const person2 = new Person('Shawn', 19, 'England');
            person2.welcome();
            
            // Kiểm tra prototype chain
            console.log(person1.__proto__ === Person.prototype); // true
            console.log(person1.constructor === Person); // true
        });
    </script>
</body>
</html>

Kết quả

Welcome Rohan age: 22 city: Delhi
Welcome Shawn age: 19 city: England

ES6 Class Syntax (Syntax sugar)

class Person {
    constructor(name, age, city) {
        this.name = name;
        this.age = age;
        this.city = city;
    }
    
    welcome() {
        console.log(`Welcome ${this.name} age: ${this.age} city: ${this.city}`);
    }
}

// Kế thừa với extends
class Student extends Person {
    constructor(name, age, city, studentId) {
        super(name, age, city); // Gọi constructor cha
        this.studentId = studentId;
    }
    
    study() {
        console.log(`${this.name} đang học...`);
    }
}

const student = new Student('Minh', 20, 'Hanoi', 'SV001');
student.welcome(); // Từ class cha
student.study();   // Method riêng

Prototype Chain

student → Student.prototype → Person.prototype → Object.prototype → null

Best Practices

  • Định nghĩa method trên prototype, không phải trong constructor (tiết kiệm bộ nhớ)
  • Dùng Object.create() cho kế thừa thuần prototype
  • Ưu tiên class syntax cho code hiện đại
  • Tránh sửa đổi Object.prototype hoặc built-in prototypes