Prototype trong JavaScript
Javascript
200
prototype
3
White

Đinh Văn Cảnh viết ngày 04/01/2018

Prototype là khái niệm cốt lõi trong JavaScript và là cơ chế quan trọng trong việc thực thi mô hình OOP trong JavaScript (nhưng không thực sự không hoàn chỉnh như trong các ngôn ngữ class-based khác), vì như đã biết, trong JavaScript, không có khái niệm class như các ngôn ngữ hướng đối tượng khác như Java hay C#. Bài viết này sẽ trình bày sơ lược về khái niệm này.

Prototype object

Để dễ hiểu, chúng ta xem xét function sau:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Khi function Person được tạo, mặc định nó sẽ có một property có tên là prototype (lưu ý là function trong JavaScript cũng là một object). Property này là một object mà ban đầu chỉ có chứa một property là constructor trỏ ngược lại function Person. Và khi function Person này được gọi với từ khóa new, object mới được tạo sẽ kế thừa tất cả các property từ Peron.prototype. Để kiểm tra, chúng ta thêm vào Person.prototype một method là showFullName() như sau:

Person.prototype.showFullName = function() {
    console.log(this.firstName + ' ' + this.lastName);
}

var justin = new Person('Justin', 'Vo');
console.log(justin); // Person {firstName: "Justin", lastName: "Vo"}
justin.showFullName(); // Justin Vo

Người ta còn gọi Person.prototypeprototype object hay gọn hơn là prototype của object justin, cũng như bất kì object nào được tạo với cú pháp new Person(...).

var david = new Person('David', 'Truong');
console.log(david); // Person {firstName: "David", lastName: "Truong"}
david.showFullName(); // David Truong

Thật ra chúng ta có thể khai báo method showFullName() ngay bên trong function Person. Tuy nhiên, do method showFullName() là giống nhau ở mọi object, nên chúng ta đưa nó lên Person.prototype để các object kế thừa lại (nguyên lý Don't Repeat Yourself - DRY). Và đó cũng là một trong số các best practice trong JavaScript: constructor chỉ khởi tạo các property riêng biệt cho mỗi object được tạo, còn các method áp dụng chung cho mọi object sẽ được tạo ở prototype.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.friends = [];
}

Person.prototype.showFullName = function() {
    console.log(this.firstName + ' ' + this.lastName);
}

Person.prototype.addFriend = function(friend) {
    this.friends.push(friend);
}


var vancanh = new Person('Canh', 'Dinh');
var justin = new Person('Justin', 'Vo');
var micheal = new Person('Micheal', 'Huynh');

console.log(vancanh.friends); // [];
vancanh.addFriend(justin);
vancanh.addFriend(micheal);
console.log(vancanh.friends); // [Person, Person]

Các object mặc định có sẵn trong JavaScript cũng được xây dựng theo cách tương tự như trên. Ví dụ, prototype của các object được tạo với cú pháp new Object() hoặc {}Object.prototype, các array được tạo với cú pháp new Array() hoặc []Array.prototype và tương tự như thế cho các object khác như RegExp hay Date. Object.prototype được kế thừa bởi mọi object và bản thân nó không có prototype (nói cách khác, prototype của nó là null).

Thực tế thì chúng ta không thể truy cập được prototype của một object và cũng không cần thiết phải dùng đến nó, tuy nhiên, chẳng hạn như trong Chrome, nó cho phép chúng ta truy cập vào prototype của một object thông qua một property "giả" là __proto__.

alt text

Prototype chain

Cơ chế prototype chain rất đơn giản: khi chúng ta truy cập vào một property của một object, JavaScript engine sẽ tìm property đó bên trong chính object, nếu không có nó sẽ tìm lên trên prototype của object, và cứ tiếp tục như thế cho đến khi gặp Object.prototype thì dừng và cho ra kết quả (undefined nếu không tìm thấy). Ví dụ:

var obj1 = { a: 1 };
var obj2 = Object.create(obj1);
obj2.b = 2;
console.log(obj1.a); // 1
console.log(obj2.a); // 1
console.log(obj2.b); // 2
console.log(obj2.c); // undefined

Trong ví dụ trên, Object.create() sẽ tạo một object mới obj2 với prototype là obj1. Và như đã thấy, mặc dù obj2 không có property a, nhưng chúng ta vẫn có thể truy cập nó nhờ vào cơ chế prototype chain.

Kết

Mình xin tạm dừng bài viết tại đây vì có lẽ đã khá dài. Trên đây mình đã cố gắng trình bày về prototype theo cách dễ hiểu. Hi vọng qua bài viết này sẽ giúp bạn hiểu hơn về khái niệm prototype trong JavaScript.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Đinh Văn Cảnh

4 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
2 0
Trong quá trình cài đặt các tool phục vụ cho việc lập trình trên Ubuntu, hẳn các bạn đã từng phải vật vã với đủ thứ config, chẳng hạn như khi cài J...
Đinh Văn Cảnh viết 2 tháng trước
2 0
White
1 0
Hôm nay mình xin chia sẻ với các bạn một module khá là tiện dụng của python trong việc tạo một CLI app đơn giản và nhanh chóng. Đó là module có tên...
Đinh Văn Cảnh viết 1 tháng trước
1 0
Bài viết liên quan
White
39 7
Tăng sức mạnh cho javascript với lodash Lần này mình sẽ giới thiệu 1 thư viện javascript vô cùng bá đạo có tên là "lodash]1]", có thể nói nó là LI...
Huy Hoàng Phạm viết hơn 2 năm trước
39 7
White
18 3
Giới thiệu Chắc mọi người ai cũng đã nắm hoặc nghe qua khái niệm Prototype trong JavaScript rồi phải không? Nếu chưa thì đọc trước vài tài liệu d...
Tom Luu viết 5 tháng trước
18 3
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
4 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!