Javascript có hướng đối tượng không

  • OOP là gì?
  • JavaScript có phải ngôn ngữ lập trình hướng đối tượng không?
  • OOP mà không có class à?
  • Kết luận

“JavaScript có phải ngôn ngữ lập trình hướng đối tượng không?” Tôi biết, chủ đề này đã được thảo luận rất nhiều lần, quá nhiều lần. Tuy nhiên nó luôn là một chủ đề “thời sự” nóng hổi. Mỗi khi một lập trình viên Java hoặc C# hoặc bất kỳ lập trình viên ngôn ngữ lập trình hướng đối tượng (OOP) nào khác tiếp xúc với JavaScript, anh ta đều phàn nàn về điều đó.

Anh ấy nói rằng làm việc với JavaScript là một mớ hỗn độn, rằng nó không có kiểu, nó không được cấu trúc tốt, nó có một số điểm kỳ lạ, hỗ trợ đối tượng của nó là tầm thường và chắc chắn nó không phải là ngôn ngữ OOP.

Rất nhiều ý kiến nảy ra, có người thì đồng tình, có người thì phản đối. Tuy nhiên theo tôi, trước khi khẳng định nó, bạn nên tự hỏi: điều gì làm cho một ngôn ngữ lập trình trở thành một ngôn ngữ lập trình hướng đối tượng?

OOP là gì?

Javascript có hướng đối tượng không

OOP viết tắt của Object Oriented Programing hay lập trình hướng đối tượng là một mẫu hình lập trình dựa trên khái niệm “công nghệ đối tượng”, mà trong đó, đối tượng chứa đựng các dữ liệu, các trường, thường được gọi là các thuộc tính và mã nguồn được tổ chức thành các phương thức kèm theo các yêu cầu:

  • Khả năng mô hình hóa một vấn đề thông qua các đối tượng
  • Hỗ trợ một số nguyên tắc cho phép tái sử dụng mô-đun và mã nguồn

Để đáp ứng yêu cầu đầu tiên, một ngôn ngữ phải cho phép lập trình mô tả thực tế bằng cách sử dụng các đối tượng và xác định các mối quan hệ giữa các đối tượng như sau:

  • Quan hệ liên kết: Đây là khả năng của đối tượng để tham chiếu đến một đối tượng độc lập khác
  • Quan hệ tổng hợp: Đây là khả năng của đối tượng để nhúng một hoặc nhiều đối tượng độc lập
  • Quan hệ thành phần: Đây là khả năng của đối tượng để nhúng một hoặc nhiều đối tượng phụ thuộc

Thông thường, yêu cầu thứ hai được đáp ứng nếu một ngôn ngữ hỗ trợ các nguyên tắc sau:

  • Tính đóng gói: Đây là khả năng tập trung vào một dữ liệu thực thể duy nhất và ẩn các chi tiết bên trong của nó
  • Tính kế thừa: Đây là cơ chế mà một đối tượng có được một số hoặc tất cả các thuộc tính, phương thức từ một hoặc nhiều đối tượng khác
  • Tính đa hình: Đây là khả năng xử lý các đối tượng khác nhau dựa trên kiểu dữ liệu hoặc cấu trúc của chúng
  • Tính trừu tượng: Đây là khả năng của chương trình bỏ qua hay không chú ý đến một số khía cạnh của thông tin mà nó đang trực tiếp làm việc lên, nghĩa là nó có khả năng tập trung vào những cốt lõi cần thiết.

Việc đáp ứng những yêu cầu này thường cho phép chúng ta phân loại một ngôn ngữ là Hướng đối tượng.

Vì vậy, bây giờ chúng ta biết ngôn ngữ OOP sẽ trông như thế nào. Chúng ta có thể chứng minh rằng JavaScript là một ngôn ngữ OOP không?

Hãy xem ví dụ sau:

var johnSmith = { firstName: "John", lastName: "Smith", address: { street: "123 Duncannon Street", city: "London", country: "United Kingdom" } }; var nickSmith = { firstName: "Nick", lastName: "Smith", address: { //Composition street: "321 Oxford Street", city: "London", country: "United Kingdom" } }; johnSmith.parent = nickSmith; var company = { name: "ACME Inc.", employees: [] }; company.employees.push(johnSmith); company.employees.push(nickSmith);

Code language: PHP (php)

Đây là một ví dụ về cách ba mối quan hệ cơ bản có thể được triển khai trong JavaScript.

Về tính đóng gói, các đối tượng JavaScript không quan tâm đến quyền private. Tất cả các thuộc tính và phương thức đều có thể truy cập public nếu không cẩn thận.

Tuy nhiên, chúng ta có thể áp dụng một số kỹ thuật để xác định trạng thái bên trong của đối tượng và bảo vệ nó khỏi sự truy cập từ bên ngoài: từ việc sử dụng getters và setters đến khai thác các closure.

Javascript có hướng đối tượng không

Tính kế thừa được hỗ trợ bởi JavaScript ở cấp độ cơ bản của nó thông qua cái gọi là kế thừa Prototype. Ngay cả khi một số lập trình viên có thể coi nó là một chút thô sơ, cơ chế kế thừa JavaScript hoàn toàn hiệu quả và cho phép nhận được kết quả tương tự như các ngôn ngữ OOP được công nhận rộng rãi.

Dù bạn nói gì, JavaScript có một cơ chế “mà một đối tượng có được một số hoặc tất cả các tính năng từ một hoặc nhiều đối tượng khác”, và đây là kế thừa.

Với tính đa hình, thách thức có vẻ khó hơn, bởi vì nhiều người liên kết khái niệm này với các kiểu dữ liệu. Trên thực tế, tính đa hình liên quan đến nhiều khía cạnh của một ngôn ngữ lập trình, và nó không chỉ liên quan đến các ngôn ngữ OOP.

Thông thường nó liên quan đến các mục như generics, overloading và structural subtyping. Tất cả những điều này dường như quá nhiều đối với một ngôn ngữ đơn giản và yếu như JavaScript. Điều này không đúng: trong JavaScript, chúng ta có thể triển khai các kiểu đa hình khác nhau theo nhiều cách và có thể chúng ta đã vô tình làm điều đó nhiều lần.

Và tính trừu tượng cũng vậy, nó cũng không rõ ràng như tính đa hình.

OOP mà không có class à?

“JavaScript ban đầu thực sự không có class”. Nhiều lập trình viên không coi JavaScript là một ngôn ngữ hướng đối tượng thực sự do thiếu khái niệm lớp và vì nó không thực thi tuân thủ các nguyên tắc OOP.

Tuy nhiên, chúng ta có thể thấy rằng định nghĩa không chính thức của chúng ta không có tham chiếu rõ ràng đến các lớp. Các tính năng và nguyên tắc được yêu cầu đối với các đối tượng. Các lớp không phải là một yêu cầu thực sự, nhưng đôi khi chúng là một cách thuận tiện để trừu tượng hóa các tập đối tượng có các thuộc tính chung.

Vì vậy, một ngôn ngữ có thể là Hướng đối tượng nếu nó hỗ trợ các đối tượng ngay cả khi không có lớp, như trong JavaScript.

Javascript có hướng đối tượng không

Hơn nữa, các nguyên tắc OOP cần thiết cho một ngôn ngữ sẽ được hỗ trợ. Lập trình viên có thể chọn sử dụng các cấu trúc cho phép anh ta tạo mã Hướng đối tượng hoặc không. Nhiều người chỉ trích JavaScript vì các lập trình viên có thể viết mã vi phạm các nguyên tắc OOP.

Nhưng đây chỉ là sự lựa chọn của lập trình viên, không phải ràng buộc về ngôn ngữ. Nó cũng xảy ra với các ngôn ngữ lập trình khác, chẳng hạn như C++.

Kể từ ES6, cú pháp JavaScript OOP là cú pháp giống hệt như C++, Java và C #. Tôi biết điều này có thể gây ngạc nhiên cho một số người sử dụng JavaScript nhưng nó thật tuyệt. Nó dường như đã xoá bỏ các định kiến cũ của mọi người về một ngôn ngữ không phải ngôn ngữ lập trình hướng đối tượng như JavaScript.

Kết luận

Câu chuyện đó chỉ là trước đây mà thôi, các bạn đừng để các định kiến cũ gây ảnh hướng đến suy nghĩ của bản thân về một ngôn ngữ lập trình nào nhé. Nếu ai đó hỏi tôi rằng “JavaScript có phải ngôn ngữ lập trình hướng đối tượng không?”, tất nhiên tôi sẽ khẳng định một cách rõ ràng là có nhé.

Mặc dù OOP của JavaScript không thể bằng các ngôn ngữ thuần OOP như Java, C# nhưng tôi vẫn có thể code bình thường mà không bị ảnh hưởng. Cảm ơn ES6 đã mang đến cho JavaScript một hương vị thay đổi quý giá.

Cảm ơn bạn đã theo dõi bài viết!

Các bạn có thể tham khảo các bài viết hay về JavaScript tại đây.


Hãy tham gia nhóm Học lập trình để thảo luận thêm về các vấn đề cùng quan tâm.

TỔNG HỢP TÀI LIỆU HỌC LẬP TRÌNH CƠ BẢN CHO NGƯỜI MỚI BẮT ĐẦU

KHOÁ HỌC BOOTCAMP JAVA/PHP/.NET TRỞ THÀNH LẬP TRÌNH VIÊN TRONG 5-6 THÁNG