Всі обʼєкти в JS мають т. зв. “прототип” - інший обʼєкт, в якого можна “запозичити” певні властивості. Вбудоване поле __proto__
- це посилання на цей прототип.
При зверненні до поля обʼєкта, пошук поля відбувається не лише в самому обʼєкті, але й у всіх прототипах по ланцюжку знизу вгору. На горі цього ланцюжка знаходиться спеціальний обʼєкт Object.prototype
.
const person = {
name: "John"
};
// За замовчуванням, прототипом всіх обʼєктів є вбудований Object.prototype
console.log(person.__proto__); // Object.prototype
const student = {
faculty: "Computer Science",
};
// Можна створювати довільні ланцюжки,
// вказуючи один обʼєкт в якості прототипа для іншого
student.__proto__ = person;
// `person` став прототипом для `student`
console.log(student.__proto__); // { name: 'John', age: 30 }
// Тепер `student` має доступ до двох полів:
// - свого "власного" поля `faculty`
// - і до "запозиченого" від `person` поля `name`
console.log(student.name); // John
console.log(student.faculty); // Computer Science
hasOwnProperty()
При ітераціії по всім полям, в цикл потрапляють не лише enumerable поля самого обʼєкта, але і всі “запозичені” з прототипів:
for (let key in student) {
console.log(key + ": " + student[key]);
}
// name: John
// faculty: Computer Science
Щоб уникнути цього можна використати метод hasOwnProperty()
: