Prototype Chain

Prototype chain

Một thuộc tính của object mà tìm trên con không có sẽ tìm lên cha, nếu không có tiếp tục tìm lên ông và cứ tiếp tục cho đến đối tượng gốc là Object.prototype

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let animal = {
  eats: "I can eat"
};
let tiger = {
  jumps: "I can jump"
};

tiger.__proto__ = animal;

// animal thừa kế từ Object prototype
console.log(animal.__proto__); // Object prototype

// Object prototype không có cha (cha là null)
console.log(animal.__proto__.__proto__); // null

// thuộc tính eats không có ở tiger
// thì tìm nó ở animal
console.log(tiger.eats);

// thuộc tính toString không có ở tiger
// tìm nó ở animal, cũng không có
// tìm nó ở Object
console.log(tiger.toString()); // [object Object] 

console.log(Object.prototype.toString); // [Function toString]

Vòng lặp for…in và hàm Object.keys()

Vòng lặp for...in lặp qua tất cả các thuộc tính của đối tượng và thuộc tính mà đối tượng đó được thừa kế.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let animal = {
  eats: "I can eat"
};
let tiger = {
  jumps: "I can jump"
};
tiger.__proto__ = animal;
for (let prop in tiger) {
  console.log(prop); // eats, jumps
}

Hàm Object.keys() chỉ trả về thuộc tính của đối tượng (không bao gồm thuộc tính nó thừa kế).

1
2
3
4
5
6
7
8
9
let animal = {
  eats: "I can eat"
};
let tiger = {
  jumps: "I can jump"
};
tiger.__proto__ = animal;

console.log(Object.keys(tiger)); // [ jumps ]

Hàm Object.prototype.hasOwnProperty() kiểm tra xem đó có phải thuộc tính mà đối tượng đó sở hữu không. Nếu thuộc tính mà nó thừa kế sẽ trả về false.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let animal = {
  eats: "I can eat"
};
let tiger = {
  jumps: "I can jump"
};
tiger.__proto__ = animal;
for (let prop in tiger) {
  if (tiger.hasOwnProperty(prop)) { // nếu là thuộc tính của tiger
    console.log(prop); // jumps
  }
}

Đối tượng tiger có nhiều thuộc tính khác như hasOwnProperty, toString nhưng nó không được liệt kê trong hàm for...in vì đây là các thuộc tính không liệt kê.