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

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

Рассмотрим:

x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
    //Do this
}

Это лучший способ сделать это?

Ответы

Ответ 1

Я действительно смущен ответами, которые были даны - большинство из них просто неверно. Конечно, вы можете иметь свойства объекта, имеющие undefined, null или false значения. Поэтому простое уменьшение проверки свойств на typeof this[property] или, что еще хуже, x.key даст вам полностью вводящие в заблуждение результаты.

Это зависит от того, что вы ищете. Если вы хотите узнать, физически ли объект содержит свойство (и он не идет откуда-то вверх по цепочке прототипов), тогда object.hasOwnProperty - это путь. Все современные браузеры поддерживают его. (В более ранних версиях Safari - 2.0.1 и старше отсутствовали. Но эти версии браузера редко используются.)

Если вы ищете, если объект имеет свойство на нем, которое является итерируемым (когда вы перейдете по свойствам объекта, оно появится), а затем выполните: prop in object даст вам желаемый эффект.

Так как использование hasOwnProperty, вероятно, то, что вы хотите, и учитывая, что вам может понадобиться резервный метод, я предлагаю вам следующее решение:

var obj = {
    a: undefined,
    b: null,
    c: false
};

// a, b, c all found
for ( var prop in obj ) {
    document.writeln( "Object1: " + prop );
}

function Class(){
    this.a = undefined;
    this.b = null;
    this.c = false;
}

Class.prototype = {
    a: undefined,
    b: true,
    c: true,
    d: true,
    e: true
};

var obj2 = new Class();

// a, b, c, d, e found
for ( var prop in obj2 ) {
    document.writeln( "Object2: " + prop );
}

function hasOwnProperty(obj, prop) {
    var proto = obj.__proto__ || obj.constructor.prototype;
    return (prop in obj) &&
        (!(prop in proto) || proto[prop] !== obj[prop]);
}

if ( Object.prototype.hasOwnProperty ) {
    var hasOwnProperty = function(obj, prop) {
        return obj.hasOwnProperty(prop);
    }
}

// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
    if ( hasOwnProperty(obj2, prop) ) {
        document.writeln( "Object2 w/ hasOwn: " + prop );
    }
}

Вышеописанное решение для кросс-браузера hasOwnProperty с одной оговоркой: оно не может различать случаи, когда идентичное свойство находится в прототипе и экземпляре - оно просто предполагает, что оно исходит из Прототип. Вы можете изменить его, чтобы быть более снисходительным или строгим, исходя из вашей ситуации, но по крайней мере это должно быть более полезным.

Ответ 2

С Underscore.js или (еще лучше) lodash:

_.has(x, 'key');

Что вызывает Object.prototype.hasOwnProperty, но (a) короче, и (b) использует "безопасную ссылку на hasOwnProperty" (т.е. работает, даже если hasOwnProperty перезаписывается).

В частности, lodash определяет _.has как:

   function has(object, key) {
      return object ? hasOwnProperty.call(object, key) : false;
   }
   // hasOwnProperty = Object.prototype.hasOwnProperty

Ответ 3

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


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

Таким образом, более надежный метод заключается в следующем:

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

С другой стороны, этот метод гораздо более подробен и медленнее.: -/

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

(function (undefined) {
    … your code …
    if (x.attribute !== undefined)
        … mode code …
})();

Ответ 4

Как насчет?

var x = {'key': 1};

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

Ответ 5

if (x.key !== undefined)

Armin Ronacher, кажется, уже избил меня до него, но:

Object.prototype.hasOwnProperty = function(property) {
    return this[property] !== undefined;
};

x = {'key': 1};

if (x.hasOwnProperty('key')) {
    alert('have key!');
}

if (!x.hasOwnProperty('bar')) {
    alert('no bar!');
}

Более безопасное, но более медленное решение как указано Конрадом Рудольфом и Armin Ronacher будет:

Object.prototype.hasOwnProperty = function(property) {
    return typeof this[property] !== 'undefined';
};

Ответ 6

Вы можете использовать оператор in чтобы проверить, существует ли свойство объекта:

x = {'key': 1};
alert("key" in x);

Вы также можете просмотреть все свойства объекта с помощью цикла for - in, а затем проверить наличие определенного свойства:

for (prop in x) {
    if (prop == "key") {
        //Do something
    }
}

Необходимо учитывать, является ли это свойство объекта перечислимым или нет, потому что неперечислимые свойства не будут отображаться for-in цикле for-in. Кроме того, если свойство enumerable скрывает неперечислимое свойство прототипа, оно не будет отображаться в Internet Explorer 8 и более ранних версиях.

Если вам нужен список всех свойств экземпляра, перечислимых или нет, вы можете использовать

Object.getOwnPropertyNames(x);

Это вернет массив имен всех свойств, которые существуют в объекте.

Наконец, вы можете использовать оператор typeof для прямой проверки типа данных свойства объекта:

if (typeof x.key == "undefined") {
    alert("undefined");
}

Если свойство не существует в объекте, оно вернет строку undefined. В противном случае он вернет соответствующий тип свойства. Тем не менее, обратите внимание, что это не всегда правильный способ проверки, имеет ли объект свойство или нет, потому что у вас может быть свойство, для которого установлено значение undefined, в этом случае использование typeof x.key все равно вернет true (даже если ключ все еще находится в объекте).

Обновление: Вы можете проверить, существует ли свойство, сравнивая с неопределенным свойством javascript

if (x.key === undefined) {
    alert("undefined");
}

Это должно работать, если ключ не был специально установлен на undefined для объекта x

Ответ 7

Пусть прорежут некоторую путаницу здесь. Во-первых, позвольте упростить, предполагая, что hasOwnProperty уже существует; Это верно для подавляющего большинства современных браузеров.

hasOwnProperty возвращает true, если переданное ему имя атрибута было добавлено к объекту. Он полностью не зависит от фактического значения, назначенного ему, которое может быть точно undefined.

Следовательно:

var o = {}
o.x = undefined

var a = o.hasOwnProperty('x')  // a is true
var b = o.x === undefined // b is also true

Тем не мение:

var o = {}

var a = o.hasOwnProperty('x')  // a is now false
var b = o.x === undefined // b is still true

Проблема в том, что происходит, когда объект в цепочке прототипов имеет атрибут со значением undefined? hasOwnProperty будет ложным для него, и так будет !== undefined. Тем не менее, для for..in все еще перечислить его в перечислении.

Суть в том, что нет кросс-браузерного способа (поскольку Internet Explorer не предоставляет __prototype__), чтобы определить, что определенный идентификатор не был прикреплен к объекту или чему-либо в его цепочке прототипов.

Ответ 8

Если вы ищете свойство, то "НЕТ". Вы хотите:

if ('prop' in obj) { }

В общем, вам не важно, связано ли свойство с прототипом или объектом.

Однако, поскольку вы использовали "ключ" в своем примере кода, похоже, что вы рассматриваете объект как хэш, и в этом случае ваш ответ будет иметь смысл. Все ключи хешей будут свойствами объекта, и вы избегаете дополнительных свойств, предоставленных прототипом.

Ответ Джона Ресига был очень всеобъемлющим, но я думал, что это не ясно. Особенно, когда использовать "prop" в obj ".

Ответ 9

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

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

Ответ 10

Для тестирования простых объектов используйте:    if (obj[x] !== undefined)

Если вы не знаете, какой тип объекта он использует:    if (obj.hasOwnProperty(x))

Все остальные параметры медленнее..

Подробнее

Оценка производительности 100 000 000 циклов под Nodejs для 5 вариантов, предложенных другими здесь:

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 execution time: 4s 510.427785ms
hasKey2 execution time: 0s 904.374806ms
hasKey3 execution time: 0s 760.336193ms
hasKey4 execution time: 0s 935.19901ms
hasKey5 execution time: 2s 148.189608ms

Нижняя строка, если ваш объект Obj не обязательно является простым объектом, и вы хотите избежать проверки цепи прототипа объекта и убедиться, что x принадлежит Obj напрямую, используйте "if (obj.hasOwnProperty(x))...".

В противном случае при использовании простого объекта и не беспокоясь о цепочке прототипов объекта, использование if (typeof(obj[x]) !== 'undefined')... является самым безопасным и быстрым способом.

Если вы используете простой объект в качестве хеш-таблицы и никогда не делаете ничего странного, я бы использовал if (obj[x])..., поскольку считаю его более читаемым.

Удачи.

Ответ 11

if (typeof x.key != "undefined") {

}

Поскольку

if (x.key)

не работает, если x.key разрешается false (например, x.key = "").

Ответ 12

Вы также можете использовать объект ES6 Reflect:

x = {'key': 1};
Reflect.has( x, 'key'); // returns true

Документацию по MDN для Reflect.has можно найти здесь.

Статический метод Reflect.has() работает как в операторе как функция.

Ответ 13

ОК, похоже, что у меня был правильный ответ, если вы не хотите унаследованных свойств:

if (x.hasOwnProperty('key'))

Вот некоторые другие опции для включения унаследованных свойств:

if (x.key) // Quick and dirty, but it does the same thing as below.

if (x.key !== undefined)

Ответ 14

hasOwnProperty "может использоваться для определения того, имеет ли объект указанное свойство как прямое свойство этого объекта; в отличие от оператора, этот метод не проверяет цепочку прототипов объекта."

Так что, скорее всего, для того, что кажется по вашему вопросу, вы не хотите использовать hasOwnProperty, который определяет, существует ли свойство как прикрепленное непосредственно к самому объекту,

Если вы хотите определить, существует ли свойство в цепочке прототипов, которую вы хотите использовать в основном, например:

if( prop in object ){ // do something }

Надеюсь, это поможет.

Ответ 15

Другой относительно простой способ - использовать Object.keys. Это возвращает array, что означает, что вы получаете все функции массива.

var noInfo = {};
var info = {something: 'data'};

Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true

Хотя мы находимся в мире с отличной поддержкой браузеров. Поскольку этот вопрос настолько стар, я подумал, что добавлю это: Это безопасно для использования с JS v1.8.5

Ответ 16

Не делайте этот object.hasOwnProperty(key)), это действительно плохо, потому что эти методы могут быть скрыты свойствами рассматриваемого объекта - рассмотрите { hasOwnProperty: false } - или объект может быть нулевым объектом (Object.create(null)).

Лучше всего сделать Object.prototype.hasOwnProperty.call(object, key) или:

const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
/* or */
import has from 'has'; // https://www.npmjs.com/package/has
// ...
console.log(has.call(object, key));

Ответ 17

С риском массивного downvoting, вот еще один вариант для конкретного случая.:)

Если вы хотите протестировать участника на объекте и хотите узнать, установлено ли оно для чего-то другого, кроме:

  • ''
  • ложь
  • NULL
  • undefined
  • 0 ...

то вы можете использовать:

var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
        // member is set, do something
}

Ответ 18

Вы можете использовать следующее approaches-

var obj = {a:1}
console.log('a' in obj)               //1
console.log(obj.hasOwnProperty('a'))  //2
console.log(Boolean(obj.a))         //3

Разница между следующими подходами заключается в follows-

  1. При первом и третьем подходе мы ищем не только объект, но и его цепочку прототипов. Если объект не имеет свойства, но свойство присутствует в его цепочке прототипов, он собирается дать значение true.

 var obj = {
      a:2,
      __proto__ :{b:2}
    }

    console.log('b' in obj)
    console.log(Boolean(obj.b))

Ответ 19

ECMA Script 6 решение с отражением. Создайте обертку наподобие:

/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj    The object or array to be searched.
@param key    The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
   "use strict";
   var retVal = (typeof defVal === 'undefined' ? "" : defVal);
   if ( Reflect.has( obj, key) ) {
       return Reflect.get( obj, key);
   }
   return retVal;
}  // getSafeReflectArg

Ответ 20

Существует метод "hasOwnProperty" существует на объекте, но его не рекомендуется напрямую обращаться к этому методу, потому что иногда объект имеет значение null или какое-либо свойство существует на объекте, например: { hasOwnProperty: false }

Таким образом, лучший способ:

// good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));

// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));

Ответ 21

Зачем слишком усложнять вещи, когда вы можете сделать:

var isProperty =  (objectname.keyname || "") ? true : false;

Просто и понятно в большинстве случаев...

Ответ 22

Вы также можете использовать этот компонент многократного использования с открытым исходным кодом, который я написал под названием object-hasOwnProperty.

Пример:

hasOwnProperty({foo: 'bar'}, 'foo') // => true
hasOwnProperty({foo: 'bar'}, 'bar') // => false

Это довольно просто:

function hasOwnProperty(obj: {}, prop: string|number): boolean {
  return Object.prototype.hasOwnProperty.call(obj, prop);
};

Ответ 23

Вам нужно использовать метод object.hasOwnProperty(property). Он возвращает true, если объект имеет свойство и false, если объект этого не делает.

Ответ 24

Если ключ, который вы проверяете, сохраняется в переменной, вы можете проверить его следующим образом:

x = {'key': 1};
y = 'key';
x[y];

Ответ 25

Я использовал это. что очень помогло мне, если у вас есть объекты внутри объекта

if(typeof(obj["key"])=="string"){
    alert("property");
}