2016-07-12 3 views
2

У меня есть объект, например:Есть ли более простой способ проверить наличие свойств?

var extra = { 
    field1: { 
    foo: {}, 
    bar: {} 
    } 
} 

field1 не гарантированно будет установлен, если мне нужно, чтобы проверить наличие extra.field1.foo, я должен использовать:

if(typeof extra.field1 != 'undefined') { 
    if(typeof extra.field1.foo != 'undefined') { 
     .... 
    } 
} 

Есть ли проще способ сделать чек?

ответ

3

Вы можете использовать Object.prototype.hasOwnProperty(), а также in operator. Но для простоты, вы можете проверить наличие свойств, как это: hasOwnProperty

if (extra.field1 && extra.field1.foo) { 
    // ... 
} 
+0

приятно! Раньше я полагал, что вместо этого он сделает исключение. – rox

4

Вы можете использовать оператор in.

Оператор in возвращает true, если указанное имущество находится в указанном объекте.

if ('field1' in extra && 'foo' in extra.field1) { 
    // true for foo 
} 
+0

Да это проще, чем 'typeof'. Я имею в виду, есть ли способ избежать двойной проверки 'if', слишком сложно написать – rox

+1

@rox. Вы можете использовать' && ' – gcampbell

0

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

if (extra.field1) { //if field1 is not null/undefined/zero/empty string/false 
    if (extra.field.foo) {...} 
    ... 
} 

Это не будет в безопасности, если field1 может быть 0 или пустая строка, потому что оба «falsy» значения

0

Используйте объект (проп) для выполнения этой задачи.

if (extra.hasOwnProperty('field1') && extra.field1.hasOwnProperty('foo')) { 
    // ... 
} 
0

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

if (myprop in myobj) { 
    ... 
} 

Считает, что его метод будет проверять все свойства и метод, которые имеет ваш объект, и метод, который он получает от «языка». В качестве примера:

var o = { 
    "myprop": true 
}; 

if ("toString" in o) { 
    console.log('toString exists'); 
} 

Он печатает 'ToString существует.

Если вы заинтересованы в проверке только внутри объекта, вы должны использовать:

if (Object.hasOwnProperty.call(myobject, myprop)) { 
    ... 
} 

Это позволяет избежать унаследованный метод, как toString и hasOwnProperty.

Грязный способ использует метод !!:

if (!!myobject[myprop]) { 
    .... 
} 

Таким образом, усилие, чтобы преобразовать любой myobject[myprop] к логическому значению. Проблема с этим - это когда вы можете иметь значения, которые могли бы преобразовать в false, например пустую строку или null или undefined или, конечно же, логическое значение false!

1

Вы можете создать функцию, которая принимает массив (или строку) и проверяет каждый элемент в нем, тогда вы можете проверить существование каждого вложенного свойства только с одним условным кодом.

obj1 = { 
    field1: { 
    col1: 1, 
    col2: 'a' 
    } 
}; 
function checkExistence(arr) { 
    // if arr is a string convert it into an array before checking it 
    if (typeof arr == 'string') { 
    arr=arr.split('.'); 
    } 
    checked = arr[0]; i = 1; 
    checks = window.hasOwnProperty(checked); 
    while (checks && i < arr.length) { 
    checked+='.'+arr[i]; 
    checks = typeof eval(checked) != 'undefined'; 
    ++i; 
    } 
    if (!checks) console.log(checked+' is undefnied'); 
    else console.log(checked+' is defined'); 
    return checks; 
} 
checkExistence(['obj1','field1','col1']); 
// obj1.field1.col1 is defined 
checkExistence(['obj1','field1','col3']); 
// obj1.field1.col3 is undefnied 
checkExistence(['obj1','field2','col3']); 
// obj1.field2 is undefnied 
checkExistence(['obj2','field2','col3']); 
// obj2 is undefnied 
checkExistence('obj1.field1.col1'); 
// obj1.field1.col1 is defined 

... 

if (checkExistence('obj1.field2.value1')) { 
    // do something 
} 
1

Этот метод может проверять любую глубину без ограничений.

function exists(node, chainString) { 
 
    return chainString.split('.') 
 
    .every(prop => node && prop in node ? (node = node[prop]) || true : false); 
 
} 
 

 
nodes = [ 
 
    {x: { y: { z: 43 }}}, 
 
    {x: { y: { z: undefined }}}, 
 
    {x: { y: null }}, 
 
    {x: []}, 
 
]; 
 

 
console.log(nodes.map(n => exists(n, "x.y.z")));

+0

Мне нравится это динамическое решение. Одна проблема: вы мутируете «узел», и поскольку объекты передаются по ссылке, эта мутация влияет на родительскую область. Ввести локальную переменную и присвоить ей клонированный массив: 'let [... o] = node;'. Затем вы можете мутировать этот локальный var без какого-либо вреда. – ftor

+0

О нет, вы не совершаете мутации, вы делаете переназначение. Извините, игнорируйте мой предыдущий комментарий. Отличная работа! Если вы переименуете 'exist' с' lookup', тогда я полностью счастлив: D – ftor

+0

@ LUH3417 Почему поиск? «Содержит», «существует» или «включает» - лучший выбор. –

Смежные вопросы