Как проверить, есть ли у объекта конкретное свойство в JavaScript?
Заголовок: Как проверить, имеет ли объект конкретное свойство в JavaScript?
Текст проблемы: Я работаю с объектом в JavaScript и хочу узнать, содержит ли он определённое свойство. Рассмотрим следующий пример:
x = {'key': 1};
if (x.hasOwnProperty('key')) {
// Выполнить это
}
Использую метод hasOwnProperty
, чтобы проверить наличие свойства. Есть ли другой способ сделать это? Буду благодарен за любые рекомендации или альтернативные подходы!
5 ответ(ов)
Вы можете использовать этот код (но обратите внимание на предостережение ниже):
var x = {
'key': 1
};
if ('key' in x) {
console.log('has');
}
Но будьте осторожны: выражение 'constructor' in x
вернёт true
, даже если x
- это пустой объект, так же как и 'toString' in x
и многие другие свойства. Лучше использовать Object.hasOwn(x, 'key')
.
Примечание: приведенное ниже решение сегодня в значительной степени устарело благодаря строгому режиму и методу hasOwnProperty
. Правильным решением является использование строгого режима и проверка наличия свойства с помощью obj.hasOwnProperty
. Этот ответ предшествует обоим этим концепциям, по крайней мере, в том виде, в котором они сейчас широко используются (да, он действительно старый). Рассматривайте это как историческую заметку.
Имейте в виду, что undefined
(к сожалению) не является зарезервированным словом в JavaScript, если вы не используете строгий режим. Поэтому кто-то (очевидно, кто-то другой) может прийти к великой идее переопределить его, что приведет к поломке вашего кода.
Более надежный метод выглядит следующим образом:
if (typeof(x.attribute) !== 'undefined')
С другой стороны, этот метод гораздо более многословен и также медленнее. 😕
Распространенной альтернативой является обеспечение того, чтобы undefined
действительно оставалось неопределенным, например, поместив код в функцию, которая принимает дополнительный параметр с именем undefined
, который не получает значения. Чтобы гарантировать, что ему не передается значение, вы можете просто вызвать ее немедленно, например:
(function (undefined) {
… ваш код …
if (x.attribute !== undefined)
… код в режиме …
})();
Давайте проясним некоторые моменты. Во-первых, упростим задачу, предположив, что hasOwnProperty
уже существует; это касается подавляющего большинства современных браузеров.
hasOwnProperty
возвращает true, если имя атрибута, переданное ему, было добавлено в объект. Это полностью независимо от фактического значения, присвоенного ему, которое может быть ровно undefined
.
Итак:
var o = {}
o.x = undefined
var a = o.hasOwnProperty('x') // a будет true
var b = o.x === undefined // b тоже будет true
Однако:
var o = {}
var a = o.hasOwnProperty('x') // a теперь false
var b = o.x === undefined // b по-прежнему true
Проблема возникает, когда в прототипной цепочке объекта есть атрибут со значением undefined. hasOwnProperty
вернет false для этого атрибута, и значение не будет равно undefined
. Тем не менее, при использовании конструкции for..in
он все равно будет указан в перечислении.
В конечном итоге, нет кросс-браузерного способа (так как Internet Explorer не предоставляет __prototype__
), чтобы определить, что конкретный идентификатор не был присоединен к объекту или к чему-либо в его прототипной цепочке.
Для тестирования простых объектов используйте:
if (obj[x] !== undefined)
Если вам не известен тип объекта, используйте:
if (obj.hasOwnProperty(x))
Все остальные варианты работают медленнее...
Подробности
Оценка производительности 100,000,000 циклов в Node.js для пяти предложенных тут вариантов:
function hasKey1(k, o) { return (x in obj); }
function hasKey2(k, o) { return (obj[x]); }
function hasKey3(k, o) { return (obj[x] !== undefined); }
function hasKey4(k, o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k, o) { return (obj.hasOwnProperty(x)); }
Оценка показывает, что если мы не хотим проверять прототип объекта, не следует использовать общий вариант:
if (X in Obj)...
Он медленнее в 2-6 раз в зависимости от конкретного случая использования.
Время выполнения hasKey1: 4.51 с
Время выполнения hasKey2: 0.90 с
Время выполнения hasKey3: 0.76 с
Время выполнения hasKey4: 0.93 с
Время выполнения hasKey5: 2.15 с
Итак, если ваш объект не является простым и вы хотите избежать проверки цепочки прототипов, чтобы гарантировать, что x непосредственно принадлежит объекту, используйте if (obj.hasOwnProperty(x))...
.
В противном случае, если вы работаете с простым объектом и не беспокоитесь о цепочке прототипов, использование if (typeof(obj[x]) !== 'undefined')...
будет самым безопасным и быстрым вариантом.
Если вы используете простой объект в качестве хэш-таблицы и не делаете ничего необычного, я бы рекомендовал использовать if (obj[x])...
, так как это более читаемо.
Да, это так 😃 Я думаю, вы также можете использовать Object.prototype.hasOwnProperty.call(x, 'key')
, что тоже должно работать, если у x
есть собственное свойство с названием hasOwnProperty
😃
Но это проверяет только собственные свойства. Если вы хотите проверить, есть ли у объекта свойство, которое может быть унаследованным, можете использовать typeof x.foo !== 'undefined'
.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"