Jak sprawdzić, czy anonimowy obiekt ma metodę?

145

Jak mogę sprawdzić, czy anonimowy obiekt, który został utworzony jako taki:

var myObj = { 
    prop1: 'no',
    prop2: function () { return false; }
}

czy rzeczywiście ma zdefiniowaną prop2?

prop2 będzie zawsze definiowana jako funkcja, ale dla niektórych obiektów nie jest wymagana i nie zostanie zdefiniowana.

Wypróbowałem to, co zostało tutaj zasugerowane: Jak ustalić, czy natywny obiekt JavaScript ma właściwość / metodę? ale nie sądzę, żeby to działało w przypadku anonimowych obiektów.

Omar
źródło
6
W JavaScript nie ma dużej różnicy między obiektami anonimowymi i nieanonimowymi. Pod osłoną są takie same.
vava

Odpowiedzi:

278

typeof myObj.prop2 === 'function'; poinformuje Cię, czy funkcja jest zdefiniowana.

if(typeof myObj.prop2 === 'function') {
    alert("It's a function");
} else if (typeof myObj.prop2 === 'undefined') {
    alert("It's undefined");
} else {
    alert("It's neither undefined nor a function. It's a " + typeof myObj.prop2);
}
Sean Vieira
źródło
1
spróbuj tego, jeśli chcesz sprawdzić za pomocą zmiennej dynamicznejif(typeof myObj[propoeryStr] === 'function') { ... }
Vivek
42

Chcesz hasOwnProperty():

var myObj1 = { 
	prop1: 'no',
	prop2: function () { return false; }
}
var myObj2 = { 
	prop1: 'no'
}

console.log(myObj1.hasOwnProperty('prop2')); // returns true
console.log(myObj2.hasOwnProperty('prop2')); // returns false
	

Źródła : Mozilla , Microsoft , phrogz.net .

artlung
źródło
4
to nie zadziała, jeśli umieściłeś węzeł dom wewnątrz samodzielnie wykonanego obiektu, np. jeśli var my_obj = {'node1': document.createElement('div')};to my_obj.node1.hasOwnProperty('cloneNode')jest fałszywe. jednak rozwiązanie Seana zwróci prawdę:typeof my_obj.node1.cloneNode === 'function'
mulllhausen
6
Nie zadziała, jeśli szukasz metody zdefiniowanej w prototypie.
Wilt
2
@Wilt pytanie określiło anonimowy literał obiektu.
artlung
4
@artlung Tak, twoja odpowiedź jest dobra na pytanie, chciałem po prostu zostawić ten komentarz tutaj dla innych, którzy mogą szukać podobnego rozwiązania działającego w innych przypadkach (takich jak ja) ... Nie chodziło o dyskwalifikację twojej odpowiedzi.
Wilt
2
Nie obsługuje przypadku, w którym właściwość jest zdefiniowana, ale nie jest funkcją.
matt2000
15

3 Opcje

  1. typeof myObj.prop2 === 'function' jeśli nazwa właściwości nie jest dynamiczna / generowana
  2. myObj.hasOwnProperty('prop2') jeśli nazwa właściwości jest dynamiczna i sprawdza tylko, czy jest to własność bezpośrednia (nie w dół łańcucha prototypów)
  3. 'prop2' in myObj jeśli nazwa właściwości jest dynamiczna, sprawdź łańcuch prototypów
Peter Tseng
źródło
8

Co masz na myśli mówiąc o „anonimowym obiekcie”? myObjnie jest anonimowy, ponieważ przypisałeś literał obiektowy do zmiennej. Możesz to po prostu przetestować:

if (typeof myObj.prop2 === 'function')
{
    // do whatever
}
Matt Ball
źródło
1

Musi to być jeden ze sposobów if (typeof myObj.prop1 != "undefined") {...}

Ain Tohvri
źródło
0

Wiem, że to stare pytanie, ale jestem zaskoczony, że wszystkie odpowiedzi zapewniają, że metoda istnieje i jest to funkcja, gdy PO chce tylko sprawdzić istnienie. Aby wiedzieć, że jest to funkcja (jak wielu twierdziło), możesz użyć:

typeof myObj.prop2 === 'function'

Ale możesz również użyć jako warunku:

typeof myObj.prop2

Lub nawet:

myObj.prop2

Dzieje się tak, ponieważ funkcja oblicza truei undefinedoblicza do false. Więc jeśli wiesz, że jeśli członek istnieje, może to być tylko funkcja, możesz użyć:

if(myObj.prop2) {
  <we have prop2>
}

Lub w wyrażeniu:

myObj.prop2 ? <exists computation> : <no prop2 computation>
Javier Elices
źródło