Khi xây dựng các ứng dụng JavaScript lớn hơn, sẽ sớm có nhu cầu chia nó thành các mô-đun được liên kết bởi các hợp đồng rõ ràng. Khi nói đến bảo trì dài hạn, cần cung cấp một cách để duy trì khả năng tương thích khi thay đổi giao diện. Để làm được điều đó, các ngôn ngữ hướng đối tượng dựa trên cơ chế đóng gói hoặc ẩn thông tin chi tiết triển khai khỏi người dùng của một đoạn mã, để nó có thể thay đổi mà không ảnh hưởng đến máy khách
Trong bài đăng này, chúng ta sẽ nói về Đóng gói dữ liệu trong JavaScript. Cụ thể hơn, chúng ta sẽ nói về việc đóng gói các thuộc tính đằng sau getters và setters
Một số khái niệm
JavaScript được thiết kế dựa trên nguyên tắc gõ vịt làm cơ sở
“Khi tôi nhìn thấy một con chim đi như vịt, bơi như vịt và kêu quạc quạc như vịt, tôi gọi con chim đó là vịt. ”
Nói cách khác, về cốt lõi, JavaScript là một ngôn ngữ hướng đối tượng, nhưng khác với các ngôn ngữ hướng đối tượng khác như C# và Java, trong các lớp JavaScript là các công dân hạng hai và các giao diện không tồn tại. Các đối tượng không có kiểu và do đó, mã cần được viết để giao tiếp với các đối tượng có các thuộc tính và phương thức nhất định. Hợp đồng giữa các mô-đun dựa trên một tập hợp các phương thức và thuộc tính được giả định là có trong các đối tượng được trao đổi
Đóng gói là nền tảng trong lập trình hướng đối tượng. Điều đó có nghĩa là một đối tượng nhất định sẽ có thể ẩn các chi tiết về hoạt động bên trong của chúng, để các đối tượng khác tương tác với nó không phụ thuộc vào các chi tiết triển khai của nó, mà phụ thuộc vào giao diện được thỏa thuận ở mức độ cao. Điều này làm cho cuộc sống của các nhà phát triển trở nên đơn giản hơn, cả về phía nhà cung cấp và phía người dùng, vì cả hai đều biết các chi tiết triển khai có thể thay đổi mà không phá vỡ các đối tượng máy khách
Tại sao hiển thị dữ liệu trên giao diện là một ý tưởng tồi
Trong JavaScript, một đối tượng chỉ đơn giản là một từ điển gồm các tên thuộc tính được ánh xạ lên các giá trị, khi giá trị của một thuộc tính là một hàm, chúng ta gọi nó là một phương thức. Giao diện giữa các phương thức là tập hợp các thuộc tính mà mã máy khách mong muốn tìm thấy trên một đối tượng
Nếu một đối tượng chỉ hiển thị các phương thức, thật dễ dàng để làm cho giao diện phát triển theo thời gian. Một phương thức có thể kiểm tra các tham số của nó và phản ứng tương ứng. Cũng có thể tạo các phương thức mới cung cấp các tính năng mới. Và, hỗ trợ những cái cũ điều chỉnh hành vi cũ theo hành vi mới. Với các thuộc tính không thể làm điều đó
Trong trường hợp thuộc tính, việc giữ giao diện ổn định không dễ dàng. Theo mặc định, mã máy khách có thể tham chiếu đến các thuộc tính không tồn tại của một đối tượng. Ghi vào một thuộc tính không tồn tại sẽ tạo ra nó. Đọc nó sẽ trở lại không xác định. Mã máy khách sẽ không thể phát hiện nhanh nếu nó đang sử dụng các thuộc tính không dùng nữa. Tồi tệ hơn, lỗi có thể lan sang các phần khác của mã, khiến việc phát hiện sự cố trở nên khó khăn hơn
API JavaScript tiêu chuẩn có các phương pháp có thể hữu ích trong việc tránh các sự cố như vậy. có thể đóng băng hoặc niêm phong một đối tượng, do đó không thể sử dụng các tên thuộc tính không được hỗ trợ
Getter/Setters để tiết kiệm thời gian
Ẩn các chi tiết của việc thực hiện phương pháp là dễ dàng
Getters/setters đã chính thức được đưa vào ngôn ngữ này trong ECMAScript 5. 1 [ECMA-262]. Chúng hiện được hỗ trợ trong tất cả các trình duyệt chính trên máy tính để bàn và thiết bị di động
Ý tưởng cơ bản là nó thêm cú pháp để xác định các thuộc tính của bộ truy cập dưới dạng các phương thức, thay vì các thuộc tính dữ liệu đơn giản. Một getter được xác định bởi từ khóa get, theo sau là một hàm được đặt tên theo thuộc tính, không nhận đối số và trả về giá trị của thuộc tính. Một setter được xác định bởi từ khóa set, theo sau là một hàm được đặt tên theo thuộc tính lấy giá trị mới của thuộc tính làm tham số
Ví dụ sau minh họa một getter và setter được sử dụng để xác định một thuộc tính của bộ truy cập được gọi là prop
var obj = { v: 0, get prop[] { return this.v; }, set prop[newValue] { this.v = newValue; } }; console.log[obj.prop]; obj.prop = 42; console.log[obj.prop];
đầu ra
0 42
Người ta cũng có thể tạo thuộc tính chỉ đọc bằng cách xác định getter mà không cần setter
var obj = { get prop[] { return -1; }, }; console.log[obj.prop]; obj.prop = 42; console.log[obj.prop];
đầu ra
-1 -1
Sau đó, một thuộc tính có thể được thay thế bằng một vài phương thức mà trong trường hợp việc triển khai một lớp thay đổi, có thể phản ứng với nó và điều chỉnh hành vi của lớp. Trong trường hợp xấu nhất, nó có thể đưa ra một ngoại lệ để thông báo cho người dùng rằng thuộc tính không được dùng nữa và không nên sử dụng nữa
đọc thêm
Tôi hy vọng bạn đã học được điều gì đó mới về cách thiết kế các ứng dụng tiến hóa phức tạp trong JavaScript trong bài đăng này. Trong phần này, tôi sẽ cung cấp cho bạn một vài liên kết đến các liên kết chứa nhiều thông tin hơn
bài viết giới thiệu
Phần này mang đến một số bài viết ngắn trình bày các khái niệm và cung cấp tổng quan về các API liên quan
Bài viết nâng cao hơn
Các bài viết này nói về các chủ đề liên quan nâng cao hơn như các vấn đề do getters và setters mang lại và cách giải quyết chúng