18

Как проверить, есть ли у объекта конкретное свойство в JavaScript?

18

Заголовок: Как проверить, имеет ли объект конкретное свойство в JavaScript?

Текст проблемы: Я работаю с объектом в JavaScript и хочу узнать, содержит ли он определённое свойство. Рассмотрим следующий пример:

x = {'key': 1};
if (x.hasOwnProperty('key')) {
    // Выполнить это
}

Использую метод hasOwnProperty, чтобы проверить наличие свойства. Есть ли другой способ сделать это? Буду благодарен за любые рекомендации или альтернативные подходы!

5 ответ(ов)

2

Вы можете использовать этот код (но обратите внимание на предостережение ниже):

var x = {
  'key': 1
};

if ('key' in x) {
  console.log('has');
}

Но будьте осторожны: выражение 'constructor' in x вернёт true, даже если x - это пустой объект, так же как и 'toString' in x и многие другие свойства. Лучше использовать Object.hasOwn(x, 'key').

1

Примечание: приведенное ниже решение сегодня в значительной степени устарело благодаря строгому режиму и методу hasOwnProperty. Правильным решением является использование строгого режима и проверка наличия свойства с помощью obj.hasOwnProperty. Этот ответ предшествует обоим этим концепциям, по крайней мере, в том виде, в котором они сейчас широко используются (да, он действительно старый). Рассматривайте это как историческую заметку.


Имейте в виду, что undefined (к сожалению) не является зарезервированным словом в JavaScript, если вы не используете строгий режим. Поэтому кто-то (очевидно, кто-то другой) может прийти к великой идее переопределить его, что приведет к поломке вашего кода.

Более надежный метод выглядит следующим образом:

if (typeof(x.attribute) !== 'undefined')

С другой стороны, этот метод гораздо более многословен и также медленнее. 😕

Распространенной альтернативой является обеспечение того, чтобы undefined действительно оставалось неопределенным, например, поместив код в функцию, которая принимает дополнительный параметр с именем undefined, который не получает значения. Чтобы гарантировать, что ему не передается значение, вы можете просто вызвать ее немедленно, например:

(function (undefined) {
    … ваш код …
    if (x.attribute !== undefined)
        … код в режиме …
})();
0

Давайте проясним некоторые моменты. Во-первых, упростим задачу, предположив, что 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__), чтобы определить, что конкретный идентификатор не был присоединен к объекту или к чему-либо в его прототипной цепочке.

0

Для тестирования простых объектов используйте:

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])..., так как это более читаемо.

0

Да, это так 😃 Я думаю, вы также можете использовать Object.prototype.hasOwnProperty.call(x, 'key'), что тоже должно работать, если у x есть собственное свойство с названием hasOwnProperty 😃

Но это проверяет только собственные свойства. Если вы хотите проверить, есть ли у объекта свойство, которое может быть унаследованным, можете использовать typeof x.foo !== 'undefined'.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь