← Назад к вопросам

Какие знаешь свойства прототипов?

1.0 Junior🔥 132 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Свойства и особенности прототипов в JavaScript

В JavaScript прототипы — это фундаментальный механизм прототипного наследования, который лежит в основе объектно-ориентированной модели языка. Вот ключевые свойства и концепции, связанные с прототипами:

1. __proto__ и [[Prototype]]

Каждый объект в JavaScript имеет скрытое свойство [[Prototype]], доступное через исторический геттер/сеттер __proto__. Это ссылка на другой объект — его прототип.

const animal = { eats: true };
const rabbit = { jumps: true };

rabbit.__proto__ = animal; // rabbit наследует от animal
console.log(rabbit.eats); // true (свойство найдено в прототипе)

2. Object.getPrototypeOf() и Object.setPrototypeOf()

Современные методы для работы с прототипами (предпочтительнее __proto__).

const animal = { eats: true };
const rabbit = { jumps: true };

Object.setPrototypeOf(rabbit, animal);
console.log(Object.getPrototypeOf(rabbit) === animal); // true

3. Свойство prototype у функций-конструкторов

Когда функция создается с помощью оператора new, свойство prototype этой функции становится прототипом для создаваемых объектов.

function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  return `${this.name} makes a sound`;
};

const dog = new Animal('Rex');
console.log(dog.speak()); // "Rex makes a sound"
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true

4. Цепочка прототипов (Prototype Chain)

При обращении к свойству объекта JavaScript сначала ищет его в самом объекте, затем в прототипе, затем в прототипе прототипа и так далее до null.

const grandParent = { a: 1 };
const parent = { b: 2 };
const child = { c: 3 };

Object.setPrototypeOf(parent, grandParent);
Object.setPrototypeOf(child, parent);

console.log(child.a); // 1 (через цепочку: child -> parent -> grandParent)
console.log(child.d); // undefined (свойство не найдено)

5. Object.create() для создания объектов с указанным прототипом

Создает новый объект с указанным прототипом и опциональными дескрипторами свойств.

const animal = { eats: true };
const rabbit = Object.create(animal, {
  jumps: { value: true, enumerable: true }
});

console.log(rabbit.eats); // true
console.log(rabbit.jumps); // true
console.log(Object.getPrototypeOf(rabbit) === animal); // true

6. hasOwnProperty() для проверки собственных свойств

Определяет, принадлежит ли свойство непосредственно объекту или унаследовано из прототипа.

const animal = { eats: true };
const rabbit = { jumps: true };
Object.setPrototypeOf(rabbit, animal);

console.log(rabbit.hasOwnProperty('jumps')); // true
console.log(rabbit.hasOwnProperty('eats')); // false

7. constructor свойство

Каждое свойство prototype функции по умолчанию имеет свойство constructor, которое ссылается на саму функцию.

function Animal() {}
console.log(Animal.prototype.constructor === Animal); // true

const obj = new Animal();
console.log(obj.constructor === Animal); // true

8. Изменяемость прототипов

Прототипы — это обычные объекты, поэтому их можно изменять динамически, и изменения будут видны во всех объектах, которые наследуют от этого прототипа.

function Animal(name) {
  this.name = name;
}

const dog1 = new Animal('Rex');
const dog2 = new Animal('Max');

Animal.prototype.speak = function() {
  return `${this.name} barks!`;
};

console.log(dog1.speak()); // "Rex barks!" (даже после создания объекта)
console.log(dog2.speak()); // "Max barks!"

9. Переопределение свойств прототипа

Если объект определяет собственное свойство с тем же именем, что и свойство в прототипе, оно "затеняет" (переопределяет) унаследованное свойство.

const animal = { eats: true };
const rabbit = Object.create(animal);
rabbit.eats = false; // Создаем собственное свойство

console.log(rabbit.eats); // false (собственное свойство)
console.log(animal.eats); // true (оригинальное свойство прототипа)

10. Прототип Object.prototype

Все объекты в конечном счете наследуют от Object.prototype, если только не созданы с помощью Object.create(null).

const obj = {};
console.log(obj.toString); // function toString() { [native code] }
console.log(obj.hasOwnProperty); // function hasOwnProperty() { [native code] }
console.log(Object.getPrototypeOf(Object.prototype)); // null

11. Статические методы и свойства

Свойства и методы, определенные непосредственно на функции-конструкторе (а не на ее prototype), не наследуются экземплярами — они доступны только через конструктор.

function Animal(name) {
  this.name = name;
}

Animal.staticMethod = function() {
  return 'Это статический метод';
};

Animal.prototype.instanceMethod = function() {
  return 'Это метод экземпляра';
};

const dog = new Animal('Rex');
console.log(dog.instanceMethod()); // "Это метод экземпляра"
console.log(dog.staticMethod); // undefined
console.log(Animal.staticMethod()); // "Это статический метод"

Важные особенности:

  • Производительность: Частые изменения в цепочке прототипов могут негативно сказаться на производительности
  • Совместимость: Современный JavaScript предлагает классы (синтаксический сахар над прототипами), которые делают работу с наследованием более интуитивной
  • Безопасность: Использование Object.create(null) создает "чистые" объекты без наследования от Object.prototype, что полезно для объектов-хранилищ

Понимание прототипов критически важно для глубокого понимания JavaScript, эффективной работы с наследованием и создания оптимальных архитектур приложений.