Ta cùng trở lại với chương trình tạo Winston
nhưng tôi đã thêm vào một loại đối tượng mới Hopper vì Hopper đang cảm thấy
hơi lạc lõng. Bây giờ tôi sẽ định nghĩa Hopper tương tự như Winston,
bắt đầu với hàm tạo, mang cùng thuộc tính rồi đến thủ tục draw
rồi thủ tục talk, sau đó tôi sẽ thêm một thủ tục nữa được gọi là
Hooray vì Hopper rất thích tiệc tùng còn Winston
thì không. Hiện tại ở cuối hàm tôi đã tạo
hai đối tượng Hopper mới: Little Hopper và big Hopper
đã vẽ cả hai, và gọi thủ tục talk cho đối tượng này và thủ tục Hooray cho đối tượng kia.
Thế là gọn gàng rồi.
Bây giờ, khi nhìn vào dòng mã trên này
ta sẽ thấy một thứ rất thú vị. Đó là
dòng mã này của Hopper rát giống với mã của Winston. Đặc biệt hãy nhìn vào hàm tạo. Không biết các bạn có nhớ không nhưng về cơ bản giống y đúc với hàm tạo của Winston.
Tiếp theo hàm talk này cũng giống y hệt với mã trong hàm talk của Winston
và cả hai đều có hàm draw.
Như vậy hai loại đối tượng này có rất nhiều điểm chung
và điều đó khiến Hopper và Winston trở thành hai loại đối tượng rất tương đồng
trong thế giới của chúng ta. Thử nghĩ mà xem, hầu hết loại đối tượng trong
thế giới thực bên ngoài máy tính đều mang những điểm chung nhất định
với các loại đối tượng khác.
Giống như trong thế giới động vật. Tất cả các loài động vật
đều giống nhau theo cách nào đó. Và tiếp đó ta có các loài động vật khác nhau
như con người. Và con người cũng mang những điểm chung đó
đồng thời có những điểm tương đồng riêng của giống loài.
Như vậy ta có thể coi
động vật là một loại đối tượng mang chức năng cho loại đối tượng con người kế thừa.
Ta không hoàn toàn bắt đầu từ con số 0 mà ta tích lũy chức năng từ khi còn là động vật.
Ví dụ các loài động vật đều phát ra tiếng kêu.
Nhưng con người còn sáng tạo ra ngôn ngữ.
Như vậy khái niệm đối tượng kế thừa này
cũng rất hữu ích trong lập trình.
Và ta có thể tạo một chuỗi đối tượng kế thừa trong Javascript.
Để làm được điều đó ta phải nghĩ về
những điểm chung giữa các loại đối tượng.
Và nghĩ ra một cái tên.
Vì ta sẽ tạo một loại đối tượng mới
đại diện cho đối tượng cơ sở,
nên ta sẽ gọi đó là creature’s.
Cả hai đều là sinh vật.
Như vậy ta nhập var creatures =. Bây giờ ta cần có hàm tạo.
Vậy thì ta chỉ việc chôm hàm tạo của Hopper, cũng giống như của Winston thôi.
Được rồi.
Ta cùng xem nhé.
Bây giờ ta phải...
Ta phải làm gì tiếp theo?
Có thể ta sẽ muốn thêm hàm “talk”.
Vậy, với hàm “talk”, ta lại chôm của Hopper. Nhưng tất nhiên thay vào đó ta phải đưa vào prototypre của creature.
Đã xong.
Vậy là ta đã xong loại đối tượng creature này.
Nhưng ta phải cho Hopper biết rằng Hopper nên
lấy chức năng của creature làm cơ sở.
Ta có thể làm điều đó bằng cách viết dòng này ở đây.
Ta sẽ nhập Hopper.prototype
equals object.create
creature.prototype
Tác dụng của dòng này là lệnh cho Javascript lấy chức năng từ prototype creature’s làm cơ sở cho prototype Hopper, nói cách khác, làm cơ sở cho tất cả các Hopper.
Và điều đó có nghĩa là mỗi khi tìm hàm trên Hopper, nó sẽ tìm ở prototype Hopper
trước, nhưng nếu không tìm thấy nó sẽ tìm trên prototype creature’s.
Đây chính là cái ta gọi là chuỗi prototype.
Sau khi hoàn thành, ta sẽ có thể xóa hàm talk
trên Hopper.
Vì ta đã có hàm talk trên creature rồi,
và sẽ xuất hiện trong chuỗi prototype.
Sẵn sàng chưa? Da dun da...
Thành công rồi!
Đó là bởi hàm đã được tìm thấy trên prototype creature.
Vậy ta cùng thử xóa trên Winston nữa nhé.
OK. Chương trình không chạy vì đối tượng không có thủ tục talk.
Tại sao lại thế? Tại sao lại thế? Ta có hàm tạo Winston,
thủ tục draw và ta đã xóa thủ tục talk.
Các bạn có thể thấy ta đã quên lệnh cho prototype Winston kế thừa
từ prototype creature’s.
Vì vậy dòng đó rất quan trọng.
Winston.prototype=object.create
creature.portotype.
Ta Da!
Hãy chú ý một điều quan trọng.
Tôi nhập dòng này sau khi nhập hàm tạo nhưng trước khi thêm bất kỳ thứ gì khác vào
construction prototype.
Thông thường đó sẽ là quy trình.
Ta muốn lệnh cho Javascript
ngay khi vừa bắt đầu rằng đây sẽ là cơ sở cho prototype ban đầu.
Nhưng sau đó ta tiếp tục thêm các thứ vào prototype.
Bởi có thể các Winston hoặc các Hopper có điều gì đó độc đáo
mà những sinh vật khác không có.
Ta hoàn toàn có thể chỉ định rõ những điều đó.
Được rồi. Hiện tại, nhìn vào đây ta vẫn thấy có một số mã bị lặp.
Mã hàm tạo.
Đúng không? Tổng cộng lặp 3 lần.
Ta xóa có được không?
Cùng thử xem nhé.
OK. Trông có vẻ không ổn lắm.
Vì Hopper xuất hiện ở góc trên bên trái, gần như quên mọi thứ về bản thân.
Đó là bởi Javascript không giả định ta cần cùng một hàm tạo ngay cả khi nó được làm cơ sở cho prototype.
Javascript để ta tự định nghĩa hàm tạo cho những đối tượng này.
Nhưng ta cũng có thể gọi hàm tạo từ đối tượng một cách dễ dàng.
Như cách ta vẫn làm
ta sẽ nhập creature.callthis,nickname,age,x,y
Tác dụng của dòng này (Nhìn kìa, thành công rồi. Yay). Tác dụng của nó là
gọi hàm creature, hàm tạo.
Nó gọi hàm nhưng lại đưa hàm vào và nói rằng ta nên gọi hàm tạo này như thể
được gọi từ đối tượng Hopper
và như thể được gọi cùng những đối số này.
Đây là những đối số mà Hopper được gọi cùng.
Và cuối cùng dòng mã này sẽ được thực hiện như thể nó vẫn ở đây ngay từ đầu.
Đó chính xác là điều chúng ta muốn. Và ta đã thành công.
Sau đó ta có thể tiếp tục
sao chép dòng này vào
cả hàm tạo Winston nữa.
Thành công rồi. Yay!
Được rồi. Hãy xem nhé. Ta đã gói gọn tất cả những thuộc tính và chức năng chung trong một loại đối tượng cơ sở duy nhất, creature.
Và ta đã tạo 2 loại đối tượng mở rộng từ đối tượng cơ sở này.
Chúng kế thừa một sô schức năng nhưng cũng tự thêm chức năng của riêng mình.
Điều thú vị là ta có thể thay đổi chức năng chung tại một vị trí duy nhất.
Ví dụ nếu ta muốn thay đổi tuổi thêm lần nữa ta có thể nhập + years old.
Giờ thì ai cũng có “years old” ở cuối cùng.
Hoặc ta có thể đổi hàm “talk” thành “woo”. Giờ thì tất cả các Winston và Hopper đều đang nói “sup”.
Hiện tại ta đã tìm hiểu cách tạo các loại đối tượng và kế thừa từ những loại đối tượng đó.
Các bạn có thể bắt đầu nghĩ đến công dụng của chúng trong các bản vẽ, hoạt hình, mô phỏng và trò chơi.
Ví dụ, bạn có một trò chơi, trong đó có nhiều loại nhân vật
và tất cả nhân vật đều có thể chạy nhưng chỉ một số có thể nhảy thôi.
Đó là ví dụ điển hình cho loại đối tượng và kế thừa.
Nhưng tôi cá các bạn có thể nghĩ ra còn nhiều cách hơn thế nữa.