Code Example 1: Object.hasOwn() vs hasOwnProperty()
❓ Что вернёт каждый вызов? Как метод различает собственные, унаследованные и несуществующие свойства?
Object.hasOwn():
const user = {
name: 'Иван',
age: 25
};
Object.hasOwn(user, 'name');
Object.hasOwn(user, 'age');
Object.hasOwn(user, 'toString');
Object.hasOwn(user, 'valueOf');
Object.hasOwn(user, 'email');
hasOwnProperty():
const user = {
name: 'Иван',
age: 25
};
user.hasOwnProperty('name');
user.hasOwnProperty('age');
user.hasOwnProperty('toString');
user.hasOwnProperty('email');
Code Example 2: Объекты без прототипа
❓ Почему первый вызов выбросит ошибку? Как Object.hasOwn() решает эту проблему?
const dict = Object.create(null);
dict.key = 'value';
dict.hasOwnProperty('key');
Object.hasOwn(dict, 'key');
Code Example 3: Переопределение hasOwnProperty
❓ Какая проблема в этом коде? Почему hasOwnProperty возвращает неверный результат?
const obj = {
hasOwnProperty: () => false,
secret: 'данные'
};
obj.hasOwnProperty('secret');
Object.hasOwn(obj, 'secret');
Code Example 4: Безопасный вызов
❓ Зачем нужен вызов через Object.prototype.hasOwnProperty.call()? Как Object.hasOwn() упрощает код?
const data = getSomeData();
Object.prototype.hasOwnProperty.call(data, 'key');
Object.hasOwn(data, 'key');
Code Example 5: Оператор in vs Object.hasOwn()
❓ Чем отличается оператор in от Object.hasOwn()? Что вернёт каждый вызов?
const obj = { name: 'Иван' };
'name' in obj;
'toString' in obj;
Object.hasOwn(obj, 'name');
Object.hasOwn(obj, 'toString');
Code Example 6: Symbol-ключи
❓ Работает ли Object.hasOwn() с Symbol-ключами? Что вернут вызовы?
const sym = Symbol('id');
const obj = {
[sym]: 123,
name: 'Иван'
};
Object.hasOwn(obj, sym);
Object.hasOwn(obj, 'name');
Code Example 7: Антипаттерн
❓ Какой из трёх подходов проверки свойства наиболее безопасный и почему?
function processData(data) {
if (data.hasOwnProperty('key')) { /* ... */ }
if (Object.prototype.hasOwnProperty.call(data, 'key')) { /* ... */ }
if (Object.hasOwn(data, 'key')) { /* ... */ }
}
Code Example 8: Использование в итерации
❓ Зачем нужна проверка Object.hasOwn() внутри for...in? Какая альтернатива существует?
const obj = {
a: 1,
b: 2,
c: 3
};
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
console.log(key, obj[key]);
}
}
Object.keys(obj).forEach(key => {
console.log(key, obj[key]);
});
Code Example 9: Полифилл
❓ Как работает полифилл для Object.hasOwn()? Почему внутри используется Object.prototype.hasOwnProperty.call()?
if (!Object.hasOwn) {
Object.defineProperty(Object, 'hasOwn', {
value: function(obj, prop) {
if (obj == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
return Object.prototype.hasOwnProperty.call(obj, prop);
},
configurable: true,
enumerable: false,
writable: true
});
}