indexOf, но для объектов?

Я хочу просмотреть объект и присвоить каждое из его существующих свойств переменной.

Возможны 4 свойства. У некоторых объектов есть все 4. У некоторых может быть только два.

Как я могу проверить, существует ли конкретное свойство? Есть ли эквивалент indexOf() для массивов, но вместо этого для объектов?


person gloopit    schedule 18.08.2016    source источник
comment
Очень сложно представить свой код из простого текста. Хотите показать здесь соответствующий исходный код? Это сделано для того, чтобы мы могли лучше помочь вам.   -  person Samuel Toh    schedule 18.08.2016
comment
Вы пробовали hasOwnProperty или преобразовать объект в массив с помощью Object.keys?   -  person litel    schedule 18.08.2016
comment
если свойства не могут быть ложными (например, все они являются подобъектами), то утиная печать читаема и быстра: if(obj.key1); alert(obj.key1.name);   -  person dandavis    schedule 18.08.2016
comment
false или falsey, включая 0 и другие распространенные значения.   -  person qxz    schedule 18.08.2016
comment
@qxz: да, это то, что я имел в виду, хороший звонок   -  person dandavis    schedule 18.08.2016


Ответы (4)


Если вас интересуют только свойства, установленные непосредственно в объекте (недоступные через цепочку прототипов), тогда hasOwnProperty предоставит логическое значение true, если объект имеет указанное свойство.

Например: testObject.hasOwnProperty('propertyToCheckFor') вернет true, если testObject.propertyToCheckFor существует, иначе будет false.

См. следующий код для более развернутого примера:

var obj1 = {
  a: 1
};
var obj2 = {
  a: 1,
  b: 2
};
var obj3 = {
  b: 2,
  c: 3
};
var obj4 = {
  a: 1,
  b: 2,
  c: 3
};


// For dispaly purposes
document.write('<pre>' + JSON.stringify({
  obj1: {
    hasA: obj1.hasOwnProperty('a'),
    hasB: obj1.hasOwnProperty('b'),
    hasC: obj1.hasOwnProperty('c')
  },
  obj2: {
    hasA: obj2.hasOwnProperty('a'),
    hasB: obj2.hasOwnProperty('b'),
    hasC: obj2.hasOwnProperty('c')
  },
  obj3: {
    hasA: obj3.hasOwnProperty('a'),
    hasB: obj3.hasOwnProperty('b'),
    hasC: obj3.hasOwnProperty('c')
  },
  obj4: {
    hasA: obj4.hasOwnProperty('a'),
    hasB: obj4.hasOwnProperty('b'),
    hasC: obj4.hasOwnProperty('c')
  }
}, null, 2) + '</pre>');

person Jason Cust    schedule 18.08.2016
comment
@dandavis Что? Если кто-то делает это, то он заслуживает 7-го круга ада, в котором оказался. - person Jason Cust; 18.08.2016
comment
я тоже так думал, пока не нашел его в дикой природе в электронной таблице excel о недвижимости, которая была преобразована в JSON. это была не функция, так что она просто выбросила, но это заставило меня очень заморочиться по поводу проверки членства в объекте... - person dandavis; 18.08.2016

Используйте ключевое слово in:

"key" in object

который возвращает true или false, в зависимости от того, имеет ли объект или что-либо в его цепочке прототипов это свойство.

Вы также можете использовать object.hasOwnProperty("key"), который будет только true, если объект имеет key как свойство самого себя, а не его прототипа. Пример:

var object = {};
"toString" in object; // true
object.hasOwnProperty("toString"); // false

Обратите внимание (согласно комментарию @dandavis), что если object имеет пользовательское свойство с именем hasOwnProperty, это будет сорвано; чтобы обойти это, используйте hasOwnProperty.call(object, "key"). Пример:

var a = {hasOwnProperty: Boolean};
a.hasOwnProperty('name'); // true
hasOwnProperty.call(a, 'name'); // false
person qxz    schedule 18.08.2016

Вы можете использовать деструктурирующее назначение. Если значение не определено, переменной будет присвоено значение undefined. Вы также можете проверить, определена ли переменная после деструктурирования, а затем переменная delete по ссылке.

var data = {a:1, b:2, c:3};

var {a, b, c, d} = data; // `d`: `undefined`
person guest271314    schedule 18.08.2016
comment
Обратите внимание, что это функция ES6 и не имеет широкой поддержки: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ - person csander; 18.08.2016
comment
это действительно аккуратно и чисто, но я не думаю, что это именно то, что нужно ОП, потому что так же сложно (если не сложнее) проверить лексику как член. - person dandavis; 18.08.2016

person    schedule
comment
Object.keys+forEach работает хорошо, но намного медленнее, чем отфильтрованное for-in для больших объектов... - person dandavis; 18.08.2016
comment
не используйте большие объекты ;) - person cstuncsik; 18.08.2016