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

Как происходит обновление токена?

2.3 Middle🔥 161 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

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

Проверка вхождения свойства в объект с прототипом

В JavaScript объекты могут наследовать свойства от своего прототипа (prototype chain). При проверке наличия свойства важно понимать разницу между собственными свойствами объекта и наследованными свойствами от прототипа.

Основные методы проверки

1. Оператор in - проверяет и собственные, и наследованные свойства

const obj = { name: "John" };
const child = Object.create(obj);
child.age = 25;

// in проверяет и собственные, и наследованные свойства
console.log("name" in child);  // true (из прототипа)
console.log("age" in child);   // true (собственное)
console.log("other" in child); // false

// Это полезно для проверки всех доступных свойств
if ("toString" in child) {
  console.log("Object has toString method (из Object.prototype)");
}

2. hasOwnProperty() - только собственные свойства

const parent = { name: "Parent" };
const child = Object.create(parent);
child.age = 25;

// hasOwnProperty только для собственных свойств
console.log(child.hasOwnProperty("age"));  // true
console.log(child.hasOwnProperty("name")); // false (это в прототипе)

// Для безопасности используй Object.prototype.hasOwnProperty.call()
// если свойство может быть переопределено в самом объекте
const obj = {
  hasOwnProperty: () => true, // Переопределено!
};
console.log(Object.prototype.hasOwnProperty.call(obj, "name")); // Безопасно

3. Object.getOwnPropertyDescriptor() - более мощный способ

const obj = { name: "John" };

// Получи дескриптор свойства (если оно собственное)
const descriptor = Object.getOwnPropertyDescriptor(obj, "name");
console.log(descriptor); // { value: "John", writable: true, enumerable: true, configurable: true }

// Если свойства нет или оно в прототипе - вернет undefined
const parentProp = Object.getOwnPropertyDescriptor(obj, "toString");
console.log(parentProp); // undefined

Проверка в цепочке прототипов

// Прототипная цепь
const animal = {
  move: function() { console.log("Moving"); }
};

const dog = Object.create(animal);
dog.bark = function() { console.log("Woof"); };

const myDog = Object.create(dog);
myDog.name = "Max";

// Проверка разных уровней
console.log("name" in myDog);      // true (собственное)
console.log("bark" in myDog);      // true (в dog)
console.log("move" in myDog);      // true (в animal)
console.log("toString" in myDog);  // true (в Object.prototype)

// Только собственные
console.log(myDog.hasOwnProperty("name")); // true
console.log(myDog.hasOwnProperty("bark")); // false
console.log(myDog.hasOwnProperty("move")); // false

Практические примеры

Проверка свойств в классах

class Animal {
  constructor(name) {
    this.name = name;
  }
  
  move() {
    console.log("Moving");
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
  
  bark() {
    console.log("Woof");
  }
}

const myDog = new Dog("Max", "Labrador");

// Проверка доступности свойств
console.log("bark" in myDog);       // true (метод Dog)
console.log("move" in myDog);       // true (метод Animal)
console.log("constructor" in myDog);// true (всегда в Object.prototype)

// Только собственные свойства инстанса
console.log(myDog.hasOwnProperty("name"));   // true
console.log(myDog.hasOwnProperty("breed"));  // true
console.log(myDog.hasOwnProperty("bark"));   // false (метод в prototype)

Итерация по свойствам

const obj = { a: 1, b: 2 };
Object.defineProperty(obj, "hidden", {
  value: 3,
  enumerable: false
});

const parent = { parentProp: 4 };
Object.setPrototypeOf(obj, parent);

// for...in включает наследованные свойства
for (let key in obj) {
  console.log(key); // a, b, parentProp (НЕ hidden)
}

// Object.keys() только собственные перечисляемые
console.log(Object.keys(obj)); // ["a", "b"]

// Object.getOwnPropertyNames() все собственные (включая неперечисляемые)
console.log(Object.getOwnPropertyNames(obj)); // ["a", "b", "hidden"]

// Итерация только по наследованным свойствам
for (let key in obj) {
  if (!obj.hasOwnProperty(key)) {
    console.log(key); // parentProp
  }
}

Сравнение методов

const obj = { name: "John" };
Object.defineProperty(obj, "secret", {
  value: "hidden",
  enumerable: false
});
Object.setPrototypeOf(obj, { inherited: true });

// in - проверяет доступность
"name" in obj;           // true
"inherited" in obj;      // true
"secret" in obj;         // true
"unknown" in obj;        // false

// hasOwnProperty - только собственные
obj.hasOwnProperty("name");      // true
obj.hasOwnProperty("inherited"); // false
obj.hasOwnProperty("secret");    // true

// Object.getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor(obj, "name");      // {...}
Object.getOwnPropertyDescriptor(obj, "inherited"); // undefined
Object.getOwnPropertyDescriptor(obj, "secret");    // {...}

Рекомендации для фронтенда

  1. Используй in когда нужна доступность свойства
  2. Используй hasOwnProperty() когда нужны только собственные свойства
  3. Избегай использования for...in для критичного кода - используй Object.keys() или Object.entries()
  4. Всегда используй Object.prototype.hasOwnProperty.call() для безопасности

Правильное понимание прототипов и проверки свойств — это важный аспект JavaScript и основа работы с объектами.