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.


let newString = 'string';
console.log(newString.split(''));

view raw

native.js

hosted with ❤ by GitHub

Ở đâ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


function add(a, b){
return a + b;
}
console.log(add(1, 2));

view raw

function.js

hosted with ❤ by GitHub

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.


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());

view raw

constructor.js

hosted with ❤ by GitHub

 

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.

 


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;
}

view raw

constructor.js

hosted with ❤ by GitHub

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:

 

Screen Shot 2019-08-22 at 1.31.08 pm.png

Ở đâ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.


Number.prototype.addOne = function(){
return this + 1;
}
const n = 2;
console.log(n.addOne());
//output 3

view raw

number.js

hosted with ❤ by GitHub

Ở đâ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.