Jak sprawdzić, czy właściwość obiektu istnieje ze zmienną zawierającą nazwę właściwości?

680

Sprawdzam, czy istnieje właściwość obiektu ze zmienną przechowującą przedmiotową nazwę właściwości.

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

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

To undefineddlatego, że szuka, myObj.myPropale chcę to sprawdzićmyObj.prop

Kreatywność na zboczu
źródło
2
Być może przydatne: z komentarza Pablo Cabrery z NCZOnline : „Myślę, że warto zauważyć, że jeśli hasOwnPropertymetoda zostanie nadpisana, możesz polegać na Object.prototype.hasOwnProperty.call(object, property)”.
HumanInDisguise,
10
czy stackoverflow.com/questions/4244896/... jest duplikatem tego pytania? w jaki sposób? „sprawdzanie istnienia” i „dostęp do wartości” to różne rzeczy? Popraw mnie, jeśli się mylę ....
adnan2nd
to nie jest duplikat.
Jeff Clayton,

Odpowiedzi:

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

Lub

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

Lub

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

Zauważ, że hasOwnPropertynie sprawdza odziedziczonych właściwości, podczas ingdy. Na przykład 'constructor' in myObjjest prawdą, ale myObj.hasOwnProperty('constructor')nie jest.

Rakieta Hazmat
źródło
23
hasOwnProperty()jest lepszy niż myObj[myProp](z innych odpowiedzi), ponieważ działa, nawet jeśli wartość myPropwynosi 0
Matt R
9
Operator „in” nie działa z łańcuchami. np. „length” w „qqq” spowoduje wyjątek. Więc jeśli chcesz sprawdzić cel ogólny, musisz użyć hasOwnProperty.
Jacob
1
@Jacob, co masz na myśli, mówiąc „operator„ w ”nie działa z ciągami znaków? z operatorem „in” lewe wyrażenie musi być ciągiem lub wartością, która może zostać przekształcona w ciąg. Tak, nie można napisać „długość” w „qqq”, ale nie można również napisać „qqq”. HasOwnProperty („długość”)
Wachburn
2
@Wachburn: 'qqq'.hasOwnProperty('length')jest true, można to zrobić.
Rocket Hazmat
1
@ gaurav5430 Uważam, że mam na myśli to, że jeśli myPropwynosi 0, instrukcja if wyglądałaby tak, if (myObj[0])jakby w myObjogóle miała jakieś właściwości, których wyrazem byłoby wyrażenie true. I myObj[0]może nie być właściwością, której szukasz.
Matt R
51

Możesz użyć hasOwnProperty , ale na podstawie referencji potrzebujesz cudzysłowów podczas korzystania z tej metody:

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

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

Innym sposobem jest użycie w operatorze, ale tutaj również potrzebujesz cytatów :

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

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

Adorjan Princz
źródło
6
To jest nie jak hasOwnProperty()jest realizowany.
kanon
7
To jest niepoprawne. Umieszczając cudzysłowy wokół nazwy myProp, nie odwołujesz się już do wartości myProp, raczej deklarujesz nowy ciąg () „myProp” i nie ma takiej właściwości „myProp” w myObj.
TriumphST
1
TriumpST: z MDN połączonego powyżej, „prop - Łańcuch lub symbol reprezentujący nazwę właściwości lub indeks tablicy (nie-symbole zostaną wymuszone na łańcuchy).”
Ben Creasy
To jest poprawne. Jeśli nie chcesz używać zmiennej, ale tylko jeśli istnieje określony „myProp”, potrzebujesz cudzysłowów.
Katinka Hesselink
@KatinkaHesselink: Twój komentarz wprowadza w błąd. Pytanie brzmiało: „Jak sprawdzić, czy istnieje właściwość obiektu ze zmienną przechowującą nazwę właściwości?”
Herbert Van-Vliet
26

Dziękujemy za pomoc wszystkich i dążenie do pozbycia się oświadczenia eval. Zmienne musiały być w nawiasach, a nie w notacji kropkowej. To działa i jest czysty, poprawny kod.

Każda z nich to zmienne: appChoice, underI, underObstr.

if(typeof tData.tonicdata[appChoice][underI][underObstr] !== "undefined"){
    //enter code here
}
Kreatywność na zboczu
źródło
To dla mnie wygląda na problem. Jeśli tData.tonicdata[appChoice]wynikiem będzie wartość, która nie ma pasującej właściwości / indeksu underI, spowoduje to TypeErrorwyrzucenie.
Ynot
Pomimo swoich zamiarów dotyczących pierwszego posta, faktycznie zadałeś inne pytanie niż to, na które udzieliłeś tej odpowiedzi. Chciałeś sprawdzić istnienie nieruchomości, nie wspominasz nic o tym, jak uzyskać do niej dostęp. Co czyni tę odpowiedź niezwiązaną z rzeczywistym pytaniem.
Pasza
19

Dla własnej nieruchomości:

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

Uwaga: użycie Object.prototype.hasOwnProperty jest lepsze niż kredyt.hasOwnProperty (..), w przypadku gdy niestandardowy hasOwnProperty jest zdefiniowany w łańcuchu prototypów (co nie ma tu miejsca), jak

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

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

Aby uwzględnić odziedziczone właściwości w wyszukiwaniu, użyj operatora in : (ale musisz umieścić obiekt po prawej stronie „in”, prymitywne wartości spowodują błąd, np. „Długość” w „home” spowoduje błąd, ale „długość” w nowym ciągu („home”) nie będzie)

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

Uwaga: Można pokusić się o użycie akcesora typeof i [] jako następującego kodu, który nie zawsze działa ...

var loan = { amount: 150 };

loan.installment = undefined;

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

if(typeof loan["installment"] !== "undefined") // incorrect
{
    // will not execute
}
adnan2nd
źródło
13

O wiele bezpieczniejszym sposobem sprawdzenia, czy właściwość istnieje na obiekcie, jest użycie do wywołania pustego obiektu lub prototypu obiektu 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

Odwołanie z MDN Web Docs - Object.prototype.hasOwnProperty ()

skmasq
źródło
4
Jeśli włączasz JavaScript, który może zrobić coś złego, na przykład zastąpienie hasOwnProperty, żadna liczba takich strażników nie zapewni bezpieczeństwa Twojemu kodowi.
meustrus
@meustrus Wiem, skąd pochodzisz, ale z perspektywy biznesowej jest bardzo prawdopodobne, że niedoświadczony programista użyje tej nazwy własności, co niekoniecznie oznacza, że ​​celowo robią coś złego.
skmasq
4

Możesz używać hasOwnProperty()tak samo jak inoperatora.

Simran Kaur
źródło
Wszystko to dlatego nienawidzę javascript
pwaterz
1
@pwaterz nie nienawidzę gracza 🙄
ArchNoob
Haha, uwielbiam to :)
pwaterz