+8

Tìm hiểu về Javascript Prototype

Introduction

Javasript prototype là một trong những khái niệm quan trọng mà mỗi Javascript developer phải biết. Object function trong Javascript có 1 thuộc tính đó chính là [[Prototype]], nó đơn giản trỏ đến 1 object khác. Hầu như tất cả objects có giá trị non-null cho thuộc tính này ở thời điểm object được tạo ra. Prototype là gì và có gì đặc biệt? Chúng ta cùng tìm hiểu nhé.

Prototype

Mặc định, Javascript engine tạo nên 1 Object() function và 1 anonymous object được trỏ đến bởi Object.prototype

console.log(Object)
console.log(Object.prototype)

Object.prototype là 1 object và nó chứa khá nhiều các function thuộc tính mà chúng ta vẫn dùng như toString(), valueOf(), ... Nó còn có 1 property là contructor mà trỏ ngược về lại Object() function console.log(Object.prototype.constructor === Object); //true

Ta có 1 function Foo(), truyền vào 1 tham số và set giá trị của name bằng giá trị tham số đầu vào.

function Foo(name) {
    this.name = name;
}

Khi thực hiện những dòng lệnh trên, Javascript engine đã tạo ra 1 function tên là Foo và 1 anonymous object. Foo() function có 1 thuộc tính là prototype trỏ đến anonymous object này. Và anonymous object này có 1 constructor trỏ ngược lại về Foo() function. Thêm nữa, Foo.prototype object trỏ đến Object.prototype object thông qua [[Prototype]] (được biết với tên gọi prototype linkage). Prototype linkage được minh họa như hình dưới

Cùng tìm hiểu về cơ chế prototype linkage này nhé.

Thêm 1 phương thức whoAmI() vào Foo.prototype object.

Foo.prototype.whoAmI = function() {
    return "I am " + this.name;
}

Foo.prototype ngoài property constructor còn chứa thêm function chúng ta vừa tạo là whoAmI()


Tạo 1 instance của Foo object

var a = new Foo('a');

Khi chạy dòng lệnh trên thì Javascript engine đã tạo ra 1 object mới tên là a và link object này đến Foo.prototype object thông qua prototype linkage. Việc link từ a, đến Foo.prototype, đến Object.prototype được gọi là prototype chain.

a.whoAmI() //I am a

Khi chạy câu lệnh trên thì Javascript engine tìm kiếm hàm whoAmI ở object a đầu tiên, nếu không có thì nó sẽ tìm đến tiếp Foo.prototype object, khi chưa tìm thấy thì sẽ tiếp tục tìm hết các object trong chuỗi prototype chain. không có thì sẽ báo lỗi.


Tạo 1 instance khác của Foo object

var b = new Foo('b');

Tạo 1 method say() cho object b

b.say = function() {
    console.log('Hi from ' + this.whoAmI());
}

Vì method say() chỉ có ở object b nên chỉ object b mới gọi được method này.

b.say() //Hi from I am b

Constructor có gì đặc biệt

console.log(a.constructor === Foo); // true

object a không có constructor property, do đó Javascript engine sẽ đi tì trong chuỗi prototype để tìm constructor gần nhất cho object a. Vì object a link đến Foo.prototype à Foo.prototype chứa constructor property (mà constructor này trỏ về Foo). Nên kết quả câu lệnh trên trả về true

Shadowing

console.log(a.whoAmI()); // I am a

object a không có method whoAmI(), do đó Javascript engine đi tìm method này trong chuỗi prototype chain. Trong trường hợp này nó tìm được ở Foo.prototype và thực hiện method này. Vậy giờ chúng ta sẽ định nghĩa method whoAmI() này cho object a

a.whoAmI = function() {
    return "This is " + this.name;
}

và gọi hàm này

console.log(a.whoAmI()); // This is a

Như ta thấy thì kết quả sẽ trả về là "This is a". Method whoAmI() ở object a đã che mờ đi method whoAmI() ở Foo.prototype. Đây chính là 1 ví dụ của Shadowing

Tại sao lại phải link đến những object khác

Đến đây, bạn có thể sẽ tự hỏi là Tại sao 1 object cần link đến những object khác làm gì? Bởi vì trong Javascript không có class (với class thì chỉ cần tạo ra các class cha và các class con có thể kế thừa các method của class cha, không cần phải link), Javascript chỉ có objects, các object được tạo ra trực tiếp và mà không có class nào, các object tự định nghĩa các behavior của nó.

Kết

Như vậy chúng ta vừa có cái nhìn về Javascript prototype thông qua các ví dụ. Mình hy vọng bài viết đã giúp cho các bạn hiểu thêm 1 chút gì đó về ngôn ngữ phổ biến này.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí