Native prototype trong Javascript là gì? Nếu bạn đã từng làm qua JavaScript, sẽ có vô số lần bạn thắc mắc built-in function trong JavaScript hoạt động thế nào. Mình cũng đã luôn có cùng một câu hỏi, chúng ta có thể chuyển đổi những function của mình thành built-in function hay không vì nó quá tiện lợi trong việc sử dụng.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let newString = 'string'; | |
| console.log(newString.split('')); |
Ở đây split là một built-in function, trong khi cách thường ngày chúng ta gọi function trong JavaScript quá dài dòng và khó chịu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function add(a, b){ | |
| return a + b; | |
| } | |
| console.log(add(1, 2)); |
Vậy có cách nào để gọi function của mình giống như built-in functions không?
Hoàn toàn có thể nhưng nó rất nguy hiểm và mình cũng không khuyến khích thực hiện nó thường xuyên. Để hiểu được built-in function hoạt động thế nào, hãy xem qua kiến thức về inheritance và prototype trong JS nhé.
Prototype là gì?
Prototype trong JavaScript không ít nhiều cũng khiến cho các developer trở nên bối rối, đặc biệc là những người đã học qua hoặc có kiến thức về class, OOP, (Java, C#, etc..). Vì mãi đến khi ES2015 ra đời thì JavaScript hoàn toàn không có …class…
Vậy trước khi chúng ta lập trình như thế nào?
Function trong JavaScript có thể hoạt động như một class.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function person(name, age, year){ | |
| this.name = name; | |
| this.birthday = age; | |
| this.year = year; | |
| this.fullName = function(){ | |
| return this.name; | |
| } | |
| } | |
| const friend = new person('John', 14, 1996); | |
| console.log(friend.name()); |
Hầu hết ta đều quá quen với trường hợp này nhưng hãy nghĩ xem nếu không có class, họ đã làm cách nào để kế thừa function đó.
Trong JavaScript, mỗi object đều có thuộc tính riêng của nó nhằm liên kết nó đến một object khác. Ở đây, ta gọi nó là prototype. Chúng ta có thể xem nó như một bản sao nguyên mẫu.
Vì nó là một bản sao nguyên mẫu, dĩ nhiên ta có thể mang nó đi mọi nơi. Built-in function trong JavaScript được tạo ra dưới những thứ được gọi là prototype.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function person(name, age, year){ | |
| this.name = name; | |
| this.age = age; | |
| this.year = year; | |
| this.fullName = function(){ | |
| return this.name; | |
| } | |
| } | |
| person.prototype.getAge = function(){ | |
| return this.age; | |
| } |
Nhưng mỗi lần muốn sử dụng, chúng ta là phải khai báo constructor một lần nữa.
Lưu ý
Việc thay đổi cấu tạo của những object built-in là một điều cấm kị, vì nó ảnh hưởng rất lớn đến những đoạn code sẽ được tái sử dụng bởi những người khác. Bạn có thể sử dụng nó trong code của riêng mình nhưng tuyệt đối không nên dùng nó khi bạn có ý định viết thư viện hay bất cứ thứ gì cho người khác.
Hãy thử với đoạn sau:

Ở đây mình đã cố tính in ra mang hình một mảng rỗng (array). Nhưng những gì nó trả về không đơn thuần chỉ là một mảng rỗng mà là toàn bộ những function ta có thể làm với array. Như là [].pop(); [].map();.
Bây giờ mình thử thay đổi Number.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Number.prototype.addOne = function(){ | |
| return this + 1; | |
| } | |
| const n = 2; | |
| console.log(n.addOne()); | |
| //output 3 |
Ở đây, mọi giá trị được xem là thuộc Number đều có tác dụng. Bạn có thể thử với những thứ khác như là Object, Array, String.
Mọi built-in object đều có cùng một mẫu, các method được đặt bên trong prototype như là Array.prototype, String.prototype, Boolean.prototype và bạn hoàn toàn có khả năng biến đổi chúng hoặc thêm vào các method mới. Nhưng như mình đã nói, mình không khuyến khích bạn thay đổi chúng. Những gì mà mình đã làm nãy giờ chính xác là những gì mà các developer đã dùng để làm ra các function như spilt, join, toString, filter etc..
Vì sao nó thực sự là ý tồi khi thay đổi các prototype đã được built in, nếu bạn sử dụng nhiều thứ viện cho một dự án và họ có cùng một method trong String.prototype.add thì sẽ gây ra vô số vấn đề khác nhau bởi lẽ prototype là thuộc tính global.
