Как проверить, существует ли свойство объекта с переменной, содержащей имя свойства?

682

Я проверяю наличие свойства объекта с переменной, содержащей имя свойства, о котором идет речь.

var myObj;
myObj.prop = "exists";
var myProp = "p"+"r"+"o"+"p";

if(myObj.myProp){
    alert("yes, i have that property");
};

Это undefinedпотому, что он ищет, myObj.myPropно я хочу его проверитьmyObj.prop

Склоны Креатив
источник
2
Возможно, полезно: из комментария Пабло Кабреры в NCZOnline : «Я думаю, стоит отметить, что если hasOwnPropertyметод перезаписан, вы можете положиться на Object.prototype.hasOwnProperty.call(object, property)».
HumanInDisguise
10
является stackoverflow.com/questions/4244896/… дубликатом этого вопроса? Как так? «проверка существования» и «доступ к значению» - разные вещи? Пожалуйста, поправьте меня, если я ошибаюсь ....
adnan2nd
это не дубликат.
Джефф Клейтон

Ответы:

1310
var myProp = 'prop';
if(myObj.hasOwnProperty(myProp)){
    alert("yes, i have that property");
}

Или

var myProp = 'prop';
if(myProp in myObj){
    alert("yes, i have that property");
}

Или

if('prop' in myObj){
    alert("yes, i have that property");
}

Обратите внимание, что hasOwnPropertyне проверяет унаследованные свойства, тогда как inделает. Например, 'constructor' in myObjэто правда, но myObj.hasOwnProperty('constructor')это не так.

Ракета Хазмат
источник
23
hasOwnProperty()тогда лучше myObj[myProp](из других ответов), так как он работает, даже если значение myPropравно 0
Matt R
9
Оператор «in» не работает со строками. например, 'length' в 'qqq' выдаст исключение. Так что, если вам нужна проверка общего назначения, вам нужно использовать hasOwnProperty.
Джейкоб
1
@Jacob, что вы имеете в виду, когда говорите «оператор in не работает со строками»? с оператором "in" 'левое выражение должно быть строкой или значением, которое может быть преобразовано в строку. Да, вы не можете написать «length» в «qqq», но вы также не можете написать «qqq» .hasOwnProperty («length»)
Wachburn
2
@ Wachburn: 'qqq'.hasOwnProperty('length')есть true, вы можете сделать это.
Ракета Хазмат
1
@ gaurav5430 Я полагаю, что я имею в виду, что если myProp0, то выражение if будет выглядеть так, if (myObj[0])что если у myObjнего вообще есть какие-либо свойства, выражение получит оценку true. И, myObj[0]возможно, не та собственность, которую вы ищете.
Мэтт Р
52

Вы можете использовать hasOwnProperty , но на основе ссылки вам нужны кавычки при использовании этого метода:

if (myObj.hasOwnProperty('myProp')) {
    // do something
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

Другой способ - использовать в операторе, но здесь вам также нужны кавычки :

if ('myProp' in myObj) {
    // do something
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

Адоржан Принц
источник
6
Это не так, как hasOwnProperty()это реализовано.
канон
7
Это неверно Поместив кавычки вокруг имени myProp, вы больше не ссылаетесь на значение myProp, скорее вы объявляете новую String () для myProp, и в myObj нет такого свойства myProp.
TriumphST
1
TriumpST: из MDN, указанного выше, «prop - строка или символ, представляющий имя свойства или индекс массива (не символы будут приводиться к строкам)».
Бен
Это правильно. Если вы не хотите использовать переменную, а просто если присутствует определенный «myProp», вам нужны кавычки.
Катинка Хесселинк,
@KatinkaHesselink: Ваш комментарий вводит в заблуждение. Вопрос был «Как проверить, существует ли свойство объекта с переменной, содержащей имя свойства?»
Герберт Ван-Влит
26

Спасибо всем за помощь и настойчивость, чтобы избавиться от заявления Eval. Переменные должны быть в скобках, а не в точечных обозначениях. Это работает и чистый, правильный код.

Каждая из этих переменных - appChoice, underI, underObstr.

if(typeof tData.tonicdata[appChoice][underI][underObstr] !== "undefined"){
    //enter code here
}
Склоны Креатив
источник
Это выглядит как проблема для меня. Если в tData.tonicdata[appChoice]результате underIполучится значение, которое не имеет соответствующего свойства / индекса , это приведет к TypeErrorвыбросу.
Ynot
Несмотря на ваши намерения в своем первоначальном сообщении, вы фактически задали другой вопрос, нежели тот, на который вы предоставили этот ответ. Вы хотели проверить существование свойства, вы ничего не упомянули о том, как получить к нему доступ. Что делает этот ответ не связанным с реальным вопросом.
Фураж
19

Для собственного имущества:

var loan = { amount: 150 };
if(Object.prototype.hasOwnProperty.call(loan, "amount")) 
{ 
   //will execute
}

Примечание: использование Object.prototype.hasOwnProperty лучше, чем loan.hasOwnProperty (..), в случае, если в цепочке прототипов определен пользовательский hasOwnProperty (что здесь не так), например

var foo = {
      hasOwnProperty: function() {
        return false;
      },
      bar: 'Here be dragons'
    };

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty

Чтобы включить унаследованные свойства в находку, используйте оператор in : (но вы должны поместить объект справа от 'in', примитивные значения приведут к ошибке, например, 'length' в 'home' вызовет ошибку, но 'length' в новой строке («дом») не будет)

const yoshi = { skulk: true };
const hattori = { sneak: true };
const kuma = { creep: true };
if ("skulk" in yoshi) 
    console.log("Yoshi can skulk");

if (!("sneak" in yoshi)) 
    console.log("Yoshi cannot sneak");

if (!("creep" in yoshi)) 
    console.log("Yoshi cannot creep");

Object.setPrototypeOf(yoshi, hattori);

if ("sneak" in yoshi)
    console.log("Yoshi can now sneak");
if (!("creep" in hattori))
    console.log("Hattori cannot creep");

Object.setPrototypeOf(hattori, kuma);

if ("creep" in hattori)
    console.log("Hattori can now creep");
if ("creep" in yoshi)
    console.log("Yoshi can also creep");

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/in

Примечание. Может возникнуть соблазн использовать аксессор свойств typeof и [] в качестве следующего кода, который работает не всегда ...

var loan = { amount: 150 };

loan.installment = undefined;

if("installment" in loan) // correct
{
    // will execute
}

if(typeof loan["installment"] !== "undefined") // incorrect
{
    // will not execute
}
adnan2nd
источник
13

Гораздо более безопасный способ проверить, существует ли свойство объекта, - использовать пустой объект или прототип объекта для вызова hasOwnProperty()

var foo = {
  hasOwnProperty: function() {
    return false;
  },
  bar: 'Here be dragons'
};

foo.hasOwnProperty('bar'); // always returns false

// Use another Object's hasOwnProperty and call it with 'this' set to foo
({}).hasOwnProperty.call(foo, 'bar'); // true

// It's also possible to use the hasOwnProperty property from the Object
// prototype for this purpose
Object.prototype.hasOwnProperty.call(foo, 'bar'); // true

Ссылка из MDN Web Docs - Object.prototype.hasOwnProperty ()

skmasq
источник
4
Если вы включаете JavaScript, который может совершать что-то плохое, например переопределение hasOwnProperty, никакое количество таких охранников не сделает ваш код безопасным или защищенным.
meustrus
@meustrus Я знаю, откуда вы, но с точки зрения бизнеса весьма вероятно, что неопытный разработчик будет использовать это имя свойства, что не обязательно означает, что они намеренно делают что-то плохое.
skmasq
4

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

Симран Каур
источник
Все это ^ почему я ненавижу javascript
pwaterz
1
@pwaterz не ненавидь игрока Arch
ArchNoob
Ха-ха, люблю это :)
pwaterz