← Назад к вопросам
Как понять что цепочка прототипов дошла до конца?
2.3 Middle🔥 151 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Цепочка прототипов в JavaScript
Цепочка прототипов - это механизм наследования в JavaScript. Расскажу как она работает и как определить конец.
Что такое цепочка прототипов
Каждый объект в JavaScript имеет скрытое свойство [[Prototype]], которое указывает на его прототип:
// Создать объект
const person = {
name: 'John',
age: 30
};
// Цепочка выглядит так:
// person -> Object.prototype -> null
//
// Когда мы ищем свойство:
// 1. Сначала ищем в самом объекте (person.name)
// 2. Если не найдено, ищем в прототипе (Object.prototype)
// 3. Если не найдено, ищем в прототипе прототипа
// 4. До конца цепочки - null
console.log(person.toString); // Найдётся в Object.prototype
console.log(person.hasOwnProperty); // Тоже из Object.prototype
Как понять что цепочка закончилась
Способ 1: Проверка на null
const obj = { a: 1 };
// Получить прототип
let proto = Object.getPrototypeOf(obj);
while (proto !== null) {
console.log('Прототип:', proto);
proto = Object.getPrototypeOf(proto);
// Цикл заканчивается когда proto === null
}
// Вывод:
// Прототип: { }
// Прототип: null (КОНЕЦ ЦЕПОЧКИ)
Способ 2: Проверка с Object.prototype
const obj = { name: 'John' };
// Конец цепочки - это Object.prototype
console.log(Object.getPrototypeOf(Object.prototype)); // null
// Проверить, дошли ли мы до конца
let current = obj;
while (current !== null) {
console.log('Уровень:', current);
current = Object.getPrototypeOf(current);
}
// Результат:
// Уровень: { name: 'John' }
// Уровень: Object {} <- это Object.prototype
// Уровень: null <- КОНЕЦ
Визуализация цепочки
function visualizePrototypeChain(obj) {
let chain = [];
let current = obj;
while (current !== null) {
chain.push(current.constructor.name);
current = Object.getPrototypeOf(current);
}
return chain.join(' -> ') + ' -> null';
}
// Примеры
console.log(visualizePrototypeChain({}));
// Объект -> Object -> null
console.log(visualizePrototypeChain([]));
// Array -> Object -> null
console.log(visualizePrototypeChain('hello'));
// String -> Object -> null
Проверка принадлежности к цепочке
const animal = { eats: true };
const dog = Object.create(animal);
dog.barks = true;
// Проверить есть ли свойство в объекте или в цепочке
console.log('eats' in dog); // true (из цепочки)
console.log('barks' in dog); // true (собственное)
console.log('meows' in dog); // false (нет в цепочке)
// Проверить, собственное ли свойство
console.log(dog.hasOwnProperty('barks')); // true
console.log(dog.hasOwnProperty('eats')); // false (это в цепочке)
// Современный способ
console.log(Object.hasOwn(dog, 'barks')); // true
console.log(Object.hasOwn(dog, 'eats')); // false
Практические примеры
С функциями-конструкторами
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(this.name + ' makes a sound');
};
function Dog(name) {
Animal.call(this, name);
}
// Установить прототип
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
const dog = new Dog('Rex');
// Цепочка: dog -> Dog.prototype -> Animal.prototype -> Object.prototype -> null
console.log(Object.getPrototypeOf(dog)); // Dog.prototype
console.log(Object.getPrototypeOf(Object.getPrototypeOf(dog))); // Animal.prototype
console.log(Object.getPrototypeOf(
Object.getPrototypeOf(
Object.getPrototypeOf(dog)
)
)); // Object.prototype
console.log(
Object.getPrototypeOf(
Object.getPrototypeOf(
Object.getPrototypeOf(
Object.getPrototypeOf(dog)
)
)
)
); // null <- КОНЕЦ ЦЕПОЧКИ
С классами (ES6)
class Animal {
speak() {
return 'sound';
}
}
class Dog extends Animal {
bark() {
return 'woof';
}
}
const dog = new Dog();
// Обход цепочки
let level = 0;
let current = dog;
while (current !== null) {
console.log(`Уровень ${level}:`, current.constructor.name);
current = Object.getPrototypeOf(current);
level++;
}
// Уровень 0: Dog
// Уровень 1: Animal
// Уровень 2: Object
// Уровень 3: null
Инструменты для исследования
// 1. Получить всю цепочку в массив
function getPrototypeChain(obj) {
const chain = [obj];
let proto = Object.getPrototypeOf(obj);
while (proto !== null) {
chain.push(proto);
proto = Object.getPrototypeOf(proto);
}
return chain;
}
const arr = [1, 2, 3];
const chain = getPrototypeChain(arr);
console.log('Длина цепочки:', chain.length); // 3
console.log('Последний элемент это null?', chain[chain.length - 1] === Object.prototype);
// 2. Вывести все свойства из цепочки
function getAllProperties(obj) {
const props = new Set();
let current = obj;
while (current !== null) {
Object.getOwnPropertyNames(current).forEach(prop => props.add(prop));
current = Object.getPrototypeOf(current);
}
return Array.from(props);
}
Проверка: дошли ли до конца
const isEndOfChain = (proto) => proto === null;
const isObjectPrototype = (proto) => proto === Object.prototype;
const isLastBeforeNull = (proto) => Object.getPrototypeOf(proto) === null;
// Примеры
let current = { x: 1 };
while (current !== null) { // Проверка на null
console.log(current);
current = Object.getPrototypeOf(current);
}
Выводы
- Цепочка прототипов заканчивается когда
Object.getPrototypeOf()возвращаетnull - Перед
nullвсегда находитсяObject.prototype - Используй
Object.getPrototypeOf()для навигации по цепочке - Проверяй
proto !== nullв цикле - Используй
hasOwnProperty()илиObject.hasOwn()чтобы различить собственные свойства от унаследованных - Инспектируй цепочку в DevTools через Object tab в консоли