Hướng dẫn constructor function trong javascript - hàm tạo trong javascript
Trong Javascript, muốn khởi tạo 1 thực thể (instance object), ta sẽ bắt đầu với việc xây dựng 1 bản khuôn mẫu (constructor) và sau đó sử dụng từ khóa Bản khuôn mẫu đó, có thể là 1 constructor function (cách cũ) hoặc 1 class (từ ECMAScript 2015). Ví dụ: Cách 1: Dùng constructor function:: Dùng constructor function:
Cách 2: Dùng Class: Dùng Class
Nhưng đôi khi, mình cũng bắt gặp 1 cách khởi tạo khác: Cách 3:: Vậy thì 3 cách làm này có gì giống và khác nhau. Cách làm nào là tiện và chuẩn nhất? Để trả lời thì chúng ta hiểu rõ điều gì đã xảy ra khi sử dụng từ khóa Khi dùng
Hãy thử kiểm chứng bằng cách thực hiện lần lượt các bước trên để khởi tạo 1 instance object
Quy trình trên thể hiện rằng: instance object kế thừa các methods từ .prototype của constructor function hoặc class. Còn các properties sẽ có được bằng cách thực hiện constructor function với giá trị của 2 chính là instance object đó.instance object kế thừa các methods từ .prototype của constructor function hoặc class. Còn các properties sẽ có được bằng cách thực hiện constructor function với giá trị
của 2 chính là instance object đó.Đây là điểm làm nên sự khác biệt giữa Cách 1 và Cách 3. Ở Cách 3, các phương thức được thêm thẳng vào instance object. Do đó nếu thay đổi 1 của constructor function thì các phương thức được thêm trực tiếp như vậy sẽ không thay đổi.Cách 1 và Cách 3. Ở Cách 3, các phương thức được thêm thẳng vào instance object. Do đó nếu thay đổi 1 của constructor function thì các phương thức được thêm trực tiếp như vậy sẽ không thay đổi.
Vậy Cách 1 có khác Cách 2 không? Câu trả lời là không khác gì ngoài cú pháp viết. Instance object được tạo bằng Cách 1 hay Cách 2 đều sẽ kế thừa methods từ 1 của bản gốc, với các properties (và giá trị của từng properties) có được bằng cách thực thi constructor function.Cách 1 có khác Cách 2 không? Câu trả lời là không khác gì ngoài cú pháp viết.
Instance object được tạo bằng Cách 1 hay Cách 2 đều sẽ kế thừa methods từ 1 của bản gốc, với các properties (và giá trị của từng properties) có được bằng cách thực thi constructor function.Dễ thấy trong Cách 2, không có từ gì liên quan đến .prototype. Tuy nhiên bản chất là tất cả các methods được khai báo trong 1 class đều đã được thêm vào .prototype của class đó. Việc sử dụng cú pháp 6 sẽ tiện lợi hơn, gọn gàng dễ hiểu hơn, nhưng cũng sẽ bớt tường minh hơn.Cách 2, không có từ gì liên quan đến .prototype. Tuy nhiên bản chất là tất cả các methods được khai báo trong 1 class đều đã được thêm vào .prototype của class đó. Việc sử dụng cú pháp 6 sẽ tiện lợi hơn, gọn gàng dễ hiểu hơn,
nhưng cũng sẽ bớt tường minh hơn.Dù vậy, vấn đề vẫn chưa dừng ở đó. Từ khóa 2 cùng sự xuất hiện của 8 khiến mọi thứ phức tạp hơn một chút.Thử viết lại việc khai báo methods ở Cách 1 và Cách 3, sử dụng 8 như sau:Cách 1 và Cách 3, sử dụng 8 như sau:Cách 1
Cách 3
Tại sao Cách 3 lại hoạt động đúng, còn Cách 1 lại không?Cách 3 lại hoạt động đúng, còn Cách 1 lại không? Lí do là bởi 8 không tự define 2, mà sẽ quay ngược lại tìm giá trị của 2 tại thời điểm 8 được khai báo. Với Cách 1, tại thời điểm khai báo, 2 có giá trị là 5 hoặc 6, do đó 7 là 8. Trong khi đó với Cách 3, thời điểm khai báo chính là Bước 3 khi từ khóa new làm việc, tại đó 2 được gán giá trị chính là object 1 rồi. Do đó cách 3 sẽ hoạt động đúng.Cách 1, tại thời điểm khai báo, 2 có giá trị là 5 hoặc 6, do đó 7 là 8. Trong khi đó với Cách 3, thời điểm khai báo chính là Bước 3 khi từ khóa new làm việc, tại đó 2 được gán giá trị chính là object 1 rồi. Do đó cách 3 sẽ hoạt động đúng.Còn với việc khai báo bằng 6 (Cách 2) thì sẽ không cần quan tâm vấn đề này, do nó không sử dụng 8.Cách 2) thì sẽ không cần quan tâm vấn đề này, do nó không sử dụng 8.Kết luận: Cú pháp 6 tiện lợi hơn nhiều khi lập trình hướng đối tượng trong Javascript. Nếu bạn vẫn quyết định sử dụng các cú pháp cũ, cần nắm rõ nguyên tắc kế thừa bằng prototype và cách sử dụng 2.Tham khảo: https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Classes https://developer.mozilla.org/vi/docs/Web/JavaScript/Reference/Operators/new https://www.taniarascia.com/understanding-classes-in-javascript/ |