W JavaScript mamy kilka sposobów uzyskania właściwości obiektu, w zależności od tego, co chcemy uzyskać.
1) Object.keys()
, która zwraca wszystkie własne, wyliczalne właściwości obiektu, metodę ECMA5.
2) for...in
pętla, która zwraca wszystkie wyliczalne właściwości obiektu, niezależnie od tego, czy są to własności własne, czy też odziedziczone z łańcucha prototypów.
3) Object.getOwnPropertyNames(obj)
który zwraca wszystkie własne właściwości obiektu, niewymierne lub nie.
Mamy też takie metody, które hasOwnProperty(prop)
pozwalają nam sprawdzić, czy właściwość jest dziedziczona lub faktycznie należy do tego obiektu, a propertyIsEnumerable(prop)
co, jak sama nazwa wskazuje, pozwala nam sprawdzić, czy właściwość jest wyliczalna.
Przy tych wszystkich opcjach nie ma możliwości uzyskania niewliczalnej, niepasującej właściwości obiektu, co chcę zrobić. Czy jest na to sposób? Innymi słowy, czy mogę w jakiś sposób uzyskać listę odziedziczonych, niewliczalnych właściwości?
Dziękuję Ci.
źródło
Odpowiedzi:
Ponieważ
getOwnPropertyNames
można uzyskać niewliczalne właściwości, możesz ich użyć i połączyć z chodzeniem po łańcuchu prototypów.Przetestowałem to na Safari 5.1 i otrzymałem
Aktualizacja: Poprawiono nieco kod (dodano spacje i nawiasy klamrowe oraz poprawiono nazwę funkcji):
źródło
while(curr = Object.getPrototypeOf(cure))
ponieważ instrukcja warunkowa używa operatora przypisania zamiast operatora porównania, czy to nie zawsze zwróciło prawdę? A może ta linia zasadniczo sprawdza, czy „curr” ma prototyp?Object.getPrototypeOf(cure)
powrócinull
na górze łańcucha prototypów. Wydaje mi się, że zakłada to brak okrągłych łańcuchów prototypów!Function.prototype
nigdy nie może być prototypem „root”, ponieważ wskazuje na to łącze do prototypuObject.prototype
. FunkcjaObject.getPrototypeOf( obj )
zwraca najwyższy obiekt w łańcuchu prototypówobj
. Umożliwia śledzenie łańcucha prototypówobj
aż do jego końca (null
wartości). Nie jestem pewien, jaki jest twój problem z tym ...undefined
.Object.getPrototypeOf(John)
zwracaBoy.prototype
obiekt (tak jak powinien) - zobacz tutaj: jsfiddle.net/aeGLA/1 . Zauważ, że konstruktor nieBoy
znajduje się w łańcuchu prototypów programu . Łańcuch prototyp jest następujący: .John
John
Boy.prototype -> Object.prototype -> null
John
jego konstruktor toBoy
, aprototype
właściwośćBoy
isBoy.prototype
. WięcObject.getPrototypeOf(John)
wracaBoy.prototype
.Czystsze rozwiązanie wykorzystujące rekursję:
Edytować
Bardziej ogólne funkcje:
Ten sam szablon można zastosować za pomocą
Object.getOwnPropertySymbols
itp.źródło
Korzystanie z zestawów prowadzi do nieco czystszego rozwiązania, IMO.
źródło
Prosta iteracja w ES6:
Przykładowy bieg:
Pokaż fragment kodu
źródło
Aby uzyskać wszystkie dziedziczone właściwości lub metody dla jakiejś instancji, możesz użyć czegoś takiego
źródło
Object.getInherited
niżObject.prototype.getInherited
. Takie postępowanie eliminuje również potrzebę brzydkiego!(name == 'getInherited')
czeku. Ponadto w Twojej implementacjiprops
tablica może zawierać zduplikowane właściwości. Na koniec, jaki jest cel ignorowaniaconstructor
właściwości?Oto rozwiązanie, które wymyśliłem studiując przedmiot. Aby uzyskać wszystkie niepoliczalne, niebędące własnością
obj
obiektu, wykonajgetProperties(obj, "nonown", "nonenum");
źródło
Przykład użycia:
źródło
jeśli próbujesz zarejestrować niewliczalne właściwości obiektu nadrzędnego, np. Domyślnie metody zdefiniowane w klasie w es6 są ustawiane w prototypie, ale nie są wyliczalne.
źródło
Realizacja w moich osobistych preferencjach :)
źródło