Прототипи, proto

Всі обʼєкти в 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():