Prototype của object
Bài viết được sự cho phép của tác giả Lưu Bình An
Khi chúng ta console.log
một object của JS, sẽ thấy một property ẩn đặc biệt [[Prototype]]
, nó có thể là null
hoặc là trỏ đến một object khác
object a => [[Prototype]] => prototype object b
Điều này có nghĩa là object a kế thừa từ object b, b có gì thì a sẽ có đó
Xem thêm nhiều việc làm JavaScript hấp dẫn trên TopDev
Chúng ta không thể truy xuất trực tiếp thông qua [[Prototype]]
, mà thông qua các phương pháp khác
let animal = {
eats: true,
walk() {
alert("Animal walk");
}
}
let rabbit = {
jumps: true,
__proto__: animal}
// hoặc khai báo bằng
rabbit.__proto__ = animal;
console.log(rabbit.eats);
// => true;
rabbit.walk();
__proto__
!=[[Prototype]]
Về bản chất, __proto__
không phải là property [[Prototype]]
, chính xác thì nó là getter/setter của [[Prototype]]
Thời điểm hiện tại, không khuyến khích dùng __proto__
, thay vào đó dùng Object.getPrototypeOf/Object.setPrototypeOf
let user = {
name: "John",
surname: "Smith",
set fullName(value) {
[this.name, this.surname] = value.split(" ");
},
get fullName() {
return `${this.name} ${this.surname}`;
}
}
let admin = {
__proto__: user,
isAdmin: true
}
alert(admin.fullName);
// => John Smith
admin.fullName = "Alice Cooper";
alert(admin.fullName);// => Alice Cooper
alert(user.fullName);// => John Smith
Khi dùng prototype, không trực tiếp thay đổi property ở object cha từ object con, việc này cần thông qua một hàm setter để đảm bảo dữ liệu sẽ độc lập trên từng object.
Như ví dụ trên, this
lúc này đang trỏ đến object phía trước dấu .
, nên dữ liệu hoàn toàn độc lập, trong khi các phương thức thì share với nhau
Vòng lặp for...in
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
alert(Object.keys(rabbit));// jumps
for(let prop in rabbit) alert(prop); // jumps, then eats
Nếu không muốn chạy qua các property
kề thừa qua __prototype__
, sử dụng obj.hasOwnProperty(key)
để xác định 1 property của được kế thừa hay không
for(let prop in rabbit) {
let isOwn = rabbit.hasOwnProperty(prop);
if (isOwn) {
alert(`Our: ${prop}`);
// Our: jumps
} else {
alert(`Inherited: ${prop}`);
// Inherited: eats
}
}
Một điều thú vị, nếu để ý chúng ta không hề khai báo rabbit.hasOwnProperty
, vậy nó từ đâu mà có? và nó cũng không xuất hiện bên trong vòng lặp for...in
?
Đây là một property kế thừa từ Object
chúa, và nó đã được khai báo decriptor với giá trị enumerable: false
Đọc lại bài decriptor
Tóm tắt
- Mỗi object sẽ chứa một property đặc biệt
[[Prototype]]
, giá trị là null, hoặc trỏ đến một object khác - Sử dụng
obj.__proto__
để truy cập this
luôn trỏ đến obj hiện tại thay vì prototype objectfor..in
sẽ chạy qua tất cả property chính chủ và property được kế thừa
Bài viết gốc được đăng tải tại vuilaptrinh.com
Có thể bạn quan tâm:
- Javascript Prototype là gì?
- Vượt qua các bài phỏng vấn Javascript
- 5 cách chia một mảng lớn thành nhiều mảng nhỏ trong Javascript
Xem thêm Việc làm IT hấp dẫn trên TopDev
- i iOS 18 khi nào ra mắt? iOS 18 sẽ không hỗ trợ máy nào?
- V Về Logging: Mắt thần của bạn trên hệ thống thực
- M Middlewares – Sự tùy biến trong ứng dụng phần mềm
- Đ Đón đầu 7 xu hướng công nghệ hàng đầu trong năm 2024
- T Thực hiện “Chuẩn Hóa CV” nhận ngay quà hấp dẫn
- M METRO.digital Vietnam culture and ways of working
- G GW2790QT – Màn hình 2K tốt nhất dành cho lập trình viên
- S So sánh AWS, Google Cloud và Azure năm 2024
- D Data Analyst là gì? Chuyện nghề của một Data Analyst
- C Công nghệ nào đứng sau AI tạo ra MC ảo đang hot rần rần?