Đây là một đánh giá về những gì chúng tôi trình bày trong hướng dẫn này về thiết kế hướng đối tượng.
Khi chúng ta tạo chương trình, chúng ta thường thấy rằng chúng ta muốn tạo nhiều đối tượng khác nhau, tất cả đều có chung các thuộc tính - giống như nhiều con mèo, có màu sắc và kích thước lông hơi khác nhau, hoặc nhiều nút, với các nhãn và vị trí khác nhau. Chúng tôi muốn có thể nói "đây thường là con mèo giống như thế nào" và sau đó nói "hãy tạo ra con mèo cụ thể này, và con mèo khác này, và chúng cũng sẽ giống nhau theo một số cách và khác nhau theo một số cách. " Trong trường hợp đó, chúng tôi muốn sử dụng thiết kế hướng đối tượng để xác định các loại đối tượng và tạo các thể hiện mới của các đối tượng đó.
Để xác định một loại đối tượng trong JavaScript, trước tiên chúng ta phải xác định "hàm xây dựng". Đây là chức năng mà chúng tôi sẽ sử dụng bất cứ khi nào chúng tôi muốn tạo một phiên bản mới của loại đối tượng đó. Đây là một hàm xây dựng cho một
Bookloại đối tượng:var Book = function(title, author, numPages) {
this.title = title;
this.author = author;
this.numPages = numPages;
this.currentPage = 0;
};
Hàm lấy các đối số cho các khía cạnh sẽ khác nhau về mỗi cuốn sách - tiêu đề, tác giả và số lượng trang. Sau đó, nó đặt các thuộc tính ban đầu của đối tượng dựa trên các đối số đó, sử dụng
thistừ khóa. Khi chúng ta sử dụng thistrong một đối tượng, chúng ta đang đề cập đến thể hiện hiện tại của một đối tượng, đề cập đến chính nó. Chúng ta cần lưu trữ các thuộc tính trên thisđể đảm bảo rằng chúng ta có thể nhớ chúng sau này.
Để tạo một thể hiện của một
Bookđối tượng, chúng tôi khai báo một biến mới để lưu trữ nó, sau đó sử dụng newtừ khóa, theo sau là tên hàm xây dựng và truyền vào các đối số mà hàm tạo mong đợi:var book = new Book("Robot Dreams", "Isaac Asimov", 320);
Sau đó chúng ta có thể truy cập bất kỳ thuộc tính nào mà chúng ta lưu trữ trong đối tượng bằng cách sử dụng ký hiệu dấu chấm:
println("I loved reading " + book.title); // I loved reading Robot Dreams
println(book.author + " is my fav author"); // "Isaac Asimov" is my fav author
Chúng ta hãy đối chiếu điều này trong một phút và cho thấy điều gì sẽ xảy ra nếu chúng ta không thiết lập đúng chức năng của nhà xây dựng:
var Book = function(title, author, numPages) {
};
var book = new Book("Little Brother", "Cory Doctorow", 380);
println("I loved reading " + book.title); // I loved reading undefined
println(book.author + " is my fav author"); // undefined is my favorite author
Nếu chúng ta chuyển các đối số vào hàm xây dựng nhưng không lưu trữ chúng một cách rõ ràng
this, thì chúng ta sẽ không thể truy cập chúng sau này! Các đối tượng sẽ quên từ lâu về họ.
Khi chúng ta xác định các loại đối tượng, chúng ta thường muốn liên kết cả thuộc tính và hành vi với chúng - giống như tất cả các đối tượng mèo của chúng ta sẽ có thể meo meo () và eat (). Vì vậy, chúng ta cần có khả năng gắn các hàm vào các định nghĩa loại đối tượng của mình và chúng ta có thể làm điều đó bằng cách định nghĩa chúng trên cái được gọi là nguyên mẫu đối tượng :
Book.prototype.readItAll = function() {
this.currentPage = this.numPages;
println("You read " + this.numPages + " pages!");
};
Nó giống như cách chúng ta sẽ xác định một chức năng một cách bình thường, ngoại trừ việc chúng ta treo nó khỏi
Booknguyên mẫu thay vì chỉ xác định nó trên toàn cầu. Đó là cách JavaScript biết rằng đây là một chức năng có thể được gọi trên bất kỳ Bookđối tượng nào và chức năng này sẽ có quyền truy cập vào thiscuốn sách mà nó được gọi.
Sau đó chúng ta có thể gọi hàm (mà chúng ta gọi là một phương thức , vì nó được gắn vào một đối tượng), như vậy:
var book = new Book("Animal Farm", "George Orwell", 112);
book.readItAll(); // You read 112 pages!
Hãy nhớ rằng, toàn bộ quan điểm của thiết kế hướng đối tượng là nó giúp chúng ta dễ dàng tạo ra nhiều đối tượng liên quan ( thể hiện đối tượng ). Hãy xem mã đó:
var pirate = new Book("Pirate Cinema", "Cory Doctorow", 384);
var giver = new Book("The Giver", "Lois Lowry", 179);
var tuck = new Book("Tuck Everlasting", "Natalie Babbit", 144);
pirate.readItAll(); // You read 384 pages!
giver.readItAll(); // You read 179 pages!
tuck.readItAll(); // You read 144 pages!
Mã đó cung cấp cho chúng tôi ba cuốn sách tương tự nhau - tất cả chúng đều có cùng loại thuộc tính và hành vi, nhưng cũng khác nhau. Ngọt!
Bây giờ, nếu bạn nghĩ về thế giới, mèo và chó là những loại đối tượng khác nhau, vì vậy bạn có thể tạo các loại đối tượng khác nhau cho chúng nếu bạn đang lập trình a
Catvà a Dog. Một con mèo sẽ meow(), một con chó sẽ bark(). Nhưng chúng cũng tương tự nhau - cả mèo và chó eat(), cả hai đều có age, và a birth, và a death. Chúng đều là động vật có vú và điều đó có nghĩa là chúng có nhiều điểm chung, ngay cả khi chúng cũng khác nhau.
Trong trường hợp đó, chúng tôi muốn sử dụng ý tưởng kế thừa đối tượng . Một loại đối tượng có thể kế thừa các thuộc tính và hành vi từ một loại đối tượng cha, nhưng sau đó cũng có những điều độc đáo của riêng nó về nó. Tất cả các
Cats và Dogs có thể thừa hưởng từ đó Mammal, do đó họ sẽ không phải phát minh ra eat()từ đầu. Làm sao chúng ta có thể làm điều đó trong JavaScript?
Hãy trở lại với ví dụ cuốn sách của chúng tôi, và nói rằng
Booklà "cha mẹ" loại đối tượng, và chúng tôi muốn làm cho hai loại đối tượng mà kế thừa từ nó - Paperbackvà EBook.
Một bìa mềm cũng giống như một cuốn sách, nhưng nó có một khác nhau Điều quan trọng, ít nhất là cho chương trình của chúng tôi: nó có một ảnh bìa. Vì vậy, hàm tạo của chúng ta cần lấy bốn đối số, để có thêm thông tin đó:
var PaperBack = function(title, author, numPages, cover) {
// ...
}
Bây giờ, chúng tôi không muốn phải thực hiện tất cả các công việc mà chúng tôi đã làm trong hàm
Booktạo để ghi nhớ ba đối số đầu tiên đó - chúng tôi muốn tận dụng thực tế là mã cho điều đó sẽ giống nhau. Vì vậy, chúng ta thực sự có thể gọi hàm Booktạo từ hàm PaperBacktạo và truyền vào các đối số đó:var PaperBack = function(title, author, numPages, cover) {
Book.call(this, title, author, numPages);
// ...
};
Chúng tôi vẫn cần lưu trữ
covertài sản trong đối tượng, vì vậy chúng tôi cần thêm một dòng để chăm sóc điều đó:var PaperBack = function(title, author, numPages, cover) {
Book.call(this, title, author, numPages);
this.cover = cover;
};
Bây giờ, chúng ta có một hàm tạo cho chúng ta
PaperBack, nó giúp nó chia sẻ các thuộc tính giống như Books, nhưng chúng ta cũng muốn chúng ta PaperBackkế thừa các phương thức của nó. Đây là cách chúng tôi làm điều đó, bằng cách nói với chương trình rằng PaperBacknguyên mẫu nên dựa trên Booknguyên mẫu:PaperBack.prototype = Object.create(Book.prototype);
Chúng tôi cũng có thể muốn đính kèm hành vi bìa mềm cụ thể, như việc có thể để đốt nó, và chúng ta có thể làm điều đó bằng cách định nghĩa các chức năng trên nguyên mẫu, sau đó dòng trên:
PaperBack.prototype.burn = function() {
println("Omg, you burnt all " + this.numPages + " pages");
this.numPages = 0;
};
Và bây giờ chúng ta có thể tạo một bìa mềm mới, đọc tất cả và ghi nó!
var calvin = new PaperBack("The Essential Calvin & Hobbes", "Bill Watterson", 256, "http://ecx.images-amazon.com/images/I/61M41hxr0zL.jpg");
calvin.readItAll(); // You read 256 pages!
calvin.burn(); // Omg, you burnt all 256 pages!
(Chà, chúng ta sẽ không thực sự đốt nó, bởi vì đó là một cuốn sách tuyệt vời, nhưng có lẽ nếu chúng ta bị mắc kẹt trong một sa mạc băng giá và tuyệt vọng vì sự ấm áp và sắp chết.)
Và bây giờ bạn có thể thấy cách chúng tôi có thể sử dụng các nguyên tắc thiết kế hướng đối tượng trong JavaScript để tạo dữ liệu phức tạp hơn cho các chương trình của bạn và mô hình hóa thế giới chương trình của bạn tốt hơn.
Nhận xét
Đăng nhận xét