Możesz użyć, Object.getOwnPropertyNames()
aby uzyskać wszystkie właściwości należące do obiektu, bez względu na to, czy są one wyliczalne, czy nie. Na przykład:
console.log(Object.getOwnPropertyNames(Math));
//-> ["E", "LN10", "LN2", "LOG2E", "LOG10E", "PI", ...etc ]
Następnie można użyć, filter()
aby uzyskać tylko metody:
console.log(Object.getOwnPropertyNames(Math).filter(function (p) {
return typeof Math[p] === 'function';
}));
//-> ["random", "abs", "acos", "asin", "atan", "ceil", "cos", "exp", ...etc ]
W przeglądarkach ES3 (IE 8 i niższych) właściwości wbudowanych obiektów nie są wyliczalne. Obiekty takie jak window
i document
nie są wbudowane, są zdefiniowane przez przeglądarkę i najprawdopodobniej są policzalne według projektu.
Z ECMA-262 wydanie 3 :
Obiekt globalny
Istnieje unikalny obiekt globalny (15.1), który jest tworzony, zanim kontrola wejdzie w kontekst wykonywania. Początkowo obiekt globalny ma następujące właściwości:
• Wbudowane obiekty, takie jak Math, String, Date, parsInt itp. Mają atrybuty {DontEnum} .
• Dodatkowe właściwości zdefiniowane przez hosta. Może to obejmować właściwość, której wartością jest sam obiekt globalny; na przykład w modelu obiektu dokumentu HTML właściwością window obiektu globalnego jest sam obiekt globalny.
Gdy kontrola wchodzi w konteksty wykonawcze i podczas wykonywania kodu ECMAScript, do obiektu globalnego można dodawać dodatkowe właściwości, a właściwości początkowe można zmieniać.
Powinienem zaznaczyć, że oznacza to, że te obiekty nie są policzalnymi właściwościami obiektu Global. Jeśli przejrzysz resztę dokumentu specyfikacji, zobaczysz, że większość wbudowanych właściwości i metod tych obiektów ma { DontEnum }
ustawiony atrybut.
Aktualizacja: inny użytkownik SO, CMS, zwrócił moją uwagę na błąd IE{ DontEnum }
.
Zamiast sprawdzania atrybutu DontEnum, [Microsoft] JScript pominie dowolną właściwość w dowolnym obiekcie, w którym w łańcuchu prototypów obiektu ma właściwość o tej samej nazwie, która ma atrybut DontEnum.
Krótko mówiąc, strzeż się, nazywając właściwości obiektu. Jeśli istnieje wbudowana właściwość lub metoda prototypu o tej samej nazwie, IE pominie ją podczas korzystania z for...in
pętli.
Object.getOwnPropertyNames()
, co zwróci nawet niepoliczalne właściwości i metody.Object.getOwnPropertyNames(Array.prototype)
?W ES3 nie jest to możliwe, ponieważ właściwości mają wewnętrzny
DontEnum
atrybut, który uniemożliwia nam wyliczenie tych właściwości. Z drugiej strony ES5 zapewnia deskryptory właściwości do kontrolowania możliwości wyliczania właściwości, dzięki czemu właściwości zdefiniowane przez użytkownika i właściwości rodzime mogą korzystać z tego samego interfejsu i cieszyć się tymi samymi możliwościami, co obejmuje możliwość programowego wyświetlania właściwości niepoliczalnych.Tej
getOwnPropertyNames
funkcji można użyć do wyliczenia wszystkich właściwości przekazanego obiektu, w tym tych, których nie można wyliczyć. Następnie można zastosować prostątypeof
kontrolę, aby odfiltrować niefunkcje. Niestety, Chrome jest jedyną przeglądarką, w której obecnie działa.loguje się
["cos", "pow", "log", "tan", "sqrt", "ceil", "asin", "abs", "max", "exp", "atan2", "random", "round", "floor", "acos", "atan", "min", "sin"]
w określonej kolejności.źródło
W ten sposób otrzymasz wszystkie metody, które możesz wywołać
obj
. Obejmuje to metody, które „dziedziczy” po prototypie (jakgetMethods()
w Javie). Jeśli chcesz zobaczyć tylko te metody zdefiniowane bezpośrednio przezobj
siebie, możesz to sprawdzić za pomocąhasOwnProperty
:źródło
document
lubwindow
mam więcej szczęścia. Szczerze mówiąc, jest to trochę nieoczekiwane, nie wiem, dlaczego to nie działa dla matematyki itp.document
iwindow
są obiektami o właściwościach przeliczalnych świadczonych przez przeglądarkę, nie są one częścią wykonywania skryptów. Obiekty rodzime są i oczywiście właściwości nie są policzalne.Najnowocześniejsza obsługa przeglądarki
console.dir(obj)
, która zwróci wszystkie właściwości obiektu odziedziczonego przez konstruktor. Zobacz dokumentację Mozilli, aby uzyskać więcej informacji i bieżącą obsługę przeglądarki.źródło
Inne odpowiedzi tutaj działają dla czegoś takiego jak matematyka, która jest obiektem statycznym. Ale nie działają one dla instancji obiektu, na przykład daty. Znalazłem następujące do pracy:
https://jsfiddle.net/3xrsead0/
To nie zadziała dla czegoś takiego jak oryginalne pytanie (matematyka), więc wybierz swoje rozwiązanie w oparciu o twoje potrzeby. Publikuję to tutaj, ponieważ Google wysłało mnie na to pytanie, ale chciałem wiedzieć, jak to zrobić w przypadku instancji obiektów.
źródło
Krótka odpowiedź brzmi: nie możesz, ponieważ
Math
iDate
(z góry mojej głowy, jestem pewien, że istnieją inne) nie są normalnymi przedmiotami. Aby to zobaczyć, utwórz prosty skrypt testowy:Widzisz, że przedstawia się jako obiekt w taki sam sposób, jak robi to ogólnie dokument, ale kiedy faktycznie próbujesz zobaczyć w tym obiekcie, widzisz, że jest to kod macierzysty i coś, co nie zostało ujawnione w ten sam sposób dla wyliczenia.
źródło
Math
ma metodę statyczną, w której można wywoływać bezpośrednio jak,Math.abs()
podczas gdyDate
ma metodę statyczną podobną,Date.now()
a także metodę instancji, w której należy najpierw utworzyć nową instancję,var time = new Date()
aby wywołaćtime.getHours()
.Oczywiście będziesz musiał przefiltrować uzyskane klucze dla metody statycznej, aby uzyskać rzeczywiste nazwy metod, ponieważ możesz również uzyskać
length, name
, które nie są funkcją na liście.Ale jeśli chcemy uzyskać wszystkie dostępne metody z klasy, która rozszerza inną klasę?
Oczywiście będziesz musiał zeskanować katalog główny prototypu, np
__proto__
. Używając . Aby zaoszczędzić czas, możesz użyć poniższego skryptu, aby uzyskać metodę statyczną i metodę głębokiej instancji.Jeśli chcesz uzyskać metody z utworzonej instancji, nie zapomnij przekazać
constructor
jej.źródło
Uważam, że istnieje prosty historyczny powód, dla którego nie można wyliczyć metod wbudowanych obiektów, takich jak na przykład Array. Dlatego:
Metody są właściwościami obiektu prototypowego, powiedzmy Object.prototype. Oznacza to, że wszystkie instancje Object odziedziczą te metody. Dlatego możesz używać tych metod na dowolnym obiekcie. Powiedz na przykład .toString ().
Tak więc, jeśli metody IF byłyby policzalne, powtórzyłbym powiedz {a: 123} za pomocą: "for (key in {a: 123}) {...}" co by się stało? Ile razy ta pętla byłaby wykonywana?
W naszym przykładzie byłoby to powtórzone raz dla pojedynczego klucza „a”. ALE RÓWNIEŻ raz dla każdej wyliczalnej właściwości Object.prototype. Więc jeśli metody byłyby wyliczalne (domyślnie), wówczas każda pętla nad dowolnym obiektem również zapętlałaby wszystkie swoje odziedziczone metody.
źródło
Object.getOwnPropertyNames(Array.prototype)
na przykład