Słowo instanceof
kluczowe w JavaScript może być dość mylące, gdy pojawia się po raz pierwszy, ponieważ ludzie myślą, że JavaScript nie jest obiektowym językiem programowania.
- Co to jest?
- Jakie problemy rozwiązuje?
- Kiedy jest to właściwe, a kiedy nie?
javascript
operators
instanceof
Alon Gubkin
źródło
źródło
"foo" instanceof String
=> fałsz,1 instanceof Number
=> fałsz,{} instanceof Object
=> fałsz. Powiedz co?"foo" instanceof String => false
jest poprawna, ponieważtypeof "foo" == 'string'
.new String("foo") instanceof String => true
, ponieważtypeof String == 'function'
- należy traktować funkcję jak klasę (definicja klasy). Zmienna staje sięinstanceof
jakąśfunction
(klasą), gdy przypisujesz ją jakovar v = new AnythingWhatTypeofEqualsFunction()
. To samo dotyczy1
.typeof 1 == 'number'
- „liczba” nie jest „funkcją” :) Dalej -{} instanceof Object
jestTRUE
w węźle i we współczesnych przeglądarkach({}) instanceof Object
powrócitrue
. W rzeczywistości napisany kod spowoduje błąd.Odpowiedzi:
wystąpienie
Operand po lewej stronie (LHS) to rzeczywisty testowany obiekt na operand po prawej stronie (RHS), który jest rzeczywistym konstruktorem klasy. Podstawowa definicja to:
Oto kilka dobrych przykładów i oto przykład zaczerpnięty bezpośrednio ze strony dewelopera Mozilli :
Jedną rzeczą, o której warto wspomnieć, jest
instanceof
prawda, jeśli obiekt dziedziczy po prototypie klasy:Jest to
p instanceof Person
prawdą, ponieważp
dziedziczy poPerson.prototype
.Na prośbę PO
Dodałem mały przykład z jakimś przykładem kodu i wyjaśnieniem.
Kiedy deklarujesz zmienną, nadajesz jej określony typ.
Na przykład:
Powyższy pokazać kilka zmiennych, a mianowicie
i
,f
orazc
. Typy sąinteger
,float
i zdefiniowane przez użytkownikaCustomer
typ danych. Typy takie jak powyższe mogą być dla dowolnego języka, nie tylko JavaScript. Jednak w JavaScript, kiedy deklarujesz zmienną, nie definiujesz jawnie typuvar x
, x może być liczbą / ciągiem / typem danych zdefiniowanym przez użytkownika. Więc coinstanceof
to jest sprawdzanie obiektu, aby zobaczyć, czy jest on określonego typu, więc z góry biorącCustomer
obiekt, który możemy zrobić:Powyżej widzieliśmy, że
c
został zadeklarowany z typemCustomer
. Zmieniliśmy go i sprawdziliśmy, czy jest typu,Customer
czy nie. Pewnie, że zwraca wartość true. Następnie nadal za pomocąCustomer
obiektu sprawdzamy, czy jest toString
. Nie, zdecydowanie nieString
nowyCustomer
obiekt nieString
przedmiot. W takim przypadku zwraca wartość false.To naprawdę jest takie proste!
źródło
color1 instanceof String;
że zwróci true, ponieważ color1 jest ciągiem.person p = new person()
p jest teraz typem osoby, a nie ciągiem znaków.var zero = 0; alert(zero); zero = "0"; alert(zero)
, przeszliśmy z prymitywnejint
na prymitywnąstring
bez żadnych problemów.int
na pierwotnystring
.Jest instancja ważna, która nie wydaje się być uwzględniona w żadnym z dotychczasowych komentarzy: dziedziczenie. Zmienna oceniana za pomocą instanceof może zwrócić wartość true dla wielu „typów” z powodu dziedziczenia prototypowego.
Na przykład zdefiniujmy typ i podtyp:
Teraz, gdy mamy już kilka „klas”, wykonajmy kilka instancji i dowiedzmy się, co to są:
Widzisz tę ostatnią linię? Wszystkie „nowe” wywołania funkcji zwracają obiekt, który dziedziczy po Object. Dzieje się tak nawet w przypadku skróconego tworzenia obiektów:
A co z samymi definicjami „klasowymi”? Jakie są ich wystąpienia?
Wydaje mi się, że zrozumienie, że każdy obiekt może być instancją typu WIELOKROTNEGO, jest ważne, ponieważ ty (niepoprawnie) zakładasz, że możesz rozróżnić, powiedzieć i obiekt od funkcji za pomocą
instanceof
. Jak pokazuje ten ostatni przykład, funkcja jest obiektem.Jest to również ważne, jeśli używasz wzorców dziedziczenia i chcesz potwierdzić potomstwo obiektu metodami innymi niż pisanie kaczką.
Mam nadzieję, że pomoże każdemu odkrywać
instanceof
.źródło
SubFoo.prototype = new Foo();
możesz dodać do niego więcej metod, asubfoo instanceof Foo
czek nadal będzie pozytywny, a takżesubfoo instanceof SubFoo
Pozostałe odpowiedzi tutaj są poprawne, ale nie zajmują się tym, jak
instanceof
faktycznie działa, co może zainteresować niektórych prawników zajmujących się językiem.Każdy obiekt w JavaScript ma prototyp, dostępny poprzez
__proto__
właściwość. Funkcje mają takżeprototype
właściwość, która jest inicjałem__proto__
dla wszystkich tworzonych przez nich obiektów. Gdy funkcja jest tworzona, otrzymuje unikalny obiektprototype
.instanceof
Operator wykorzystuje tę niepowtarzalność dać odpowiedź. Oto, coinstanceof
może wyglądać, jeśli napisałeś to jako funkcję.Jest to w zasadzie parafrazowanie ECMA-262 wydanie 5.1 (znane również jako ES5), sekcja 15.3.5.3.
Zauważ, że możesz ponownie przypisać dowolny obiekt do
prototype
właściwości funkcji i możesz ponownie przypisać__proto__
właściwość obiektu po jego zbudowaniu. To da ci kilka interesujących wyników:źródło
__proto__
” nie jest dozwolone w IE. Jeśli dobrze pamiętam, bezpośrednia manipulacja właściwością nie jest również uwzględniona w specyfikacji ECMA, więc prawdopodobnie jest to zły pomysł, aby użyć jej do zadań innych niż do celów akademickich.Object.getPrototypeOf(o)
, będzie on taki sam, jak__proto__
opisujesz, ale jest zgodny z ECMAScript.Myślę, że warto zauważyć, że instanceof jest definiowany przez użycie słowa kluczowego „new” podczas deklarowania obiektu. W przykładzie z JonH;
Nie wspomniał o tym;
Określenie „new” faktycznie skopiowało stan końcowy funkcji konstruktora String do zmiennej color1 var, zamiast po prostu ustawić wartość zwracaną. Myślę, że to lepiej pokazuje, co robi nowe słowo kluczowe;
Użycie „nowego” przypisuje wartość „this” wewnątrz funkcji do zadeklarowanego var, natomiast nieużywanie go przypisuje wartość zwracaną.
źródło
new
z żadnego z typów JavaScript, co sprawia, że akceptowana odpowiedź jest bardziej myląca dla początkujących.text = String('test')
ioptions = {}
nie będą testowane przez,instanceof
ale raczej ztypeof
zamiast.Możesz go użyć do obsługi błędów i debugowania:
źródło
źródło
JavaScript jest językiem prototypowym, co oznacza, że używa prototypów do „dziedziczenia”.
instanceof
operatora sprawdza, czy funkcją konstruktoraprototype
propertype obecny jest w__proto__
łańcuchu obiektu. Oznacza to, że wykona następujące czynności (zakładając, że testObj jest obiektem funkcji):obj.__proto__ === testObj.prototype
>> czy totrue
instanceof
zwrócitrue
.obj.__proto__.__proto__ === testObj.prototype
>> jeśli totrue
instanceof
wrócitrue
.testObj.prototype
następnieinstanceof
operator powrócifalse
.Przykład:
Rozwiązano problem wygodnego sprawdzania, czy obiekt pochodzi z określonego prototypu. Na przykład, gdy funkcja odbiera obiekt, który może mieć różne prototypy. Następnie, przed użyciem metod z łańcucha prototypów, możemy użyć
instanceof
operatora, aby sprawdzić, czy te metody znajdują się na obiekcie.Przykład:
Tutaj w
talk()
funkcji najpierw sprawdza się, czy prototyp znajduje się na obiekcie. Następnie wybiera się odpowiednią metodę do wykonania. Nie wykonanie tej kontroli może spowodować wykonanie metody, która nie istnieje, a tym samym błąd odniesienia.W pewnym sensie już to omówiliśmy. Użyj go, gdy chcesz sprawdzić prototyp obiektu przed zrobieniem z nim czegoś.
źródło
PersonX.prototype.talk
, aby tatalk
funkcja mogła po prostu to zrobićperson.talk()
.__proto__
w dokumentacji, jest przestarzała -Object.getPrototype()
zamiast tego napiszNa pytanie „Kiedy jest to właściwe, a kiedy nie?”, Moje 2 centy:
instanceof
jest rzadko przydatny w kodzie produkcyjnym, ale przydatny w testach, w których chcesz stwierdzić, że Twój kod zwraca / tworzy obiekty poprawnych typów. Wyrażając się jasno o rodzajach obiektów, które kod zwraca / tworzy, twoje testy stają się potężniejsze jako narzędzie do zrozumienia i dokumentowania kodu.źródło
instanceof
jest tylko cukrem syntaktycznym dlaisPrototypeOf
:instanceof
zależy tylko od prototypu konstruktora obiektu.Konstruktor jest po prostu normalną funkcją. Ściśle mówiąc, jest to obiekt funkcji, ponieważ wszystko jest obiektem w JavaScript. I ten obiekt funkcji ma prototyp, ponieważ każda funkcja ma prototyp.
Prototyp to po prostu normalny obiekt, który znajduje się w łańcuchu prototypów innego obiektu. Oznacza to, że będąc w łańcuchu prototypów innego obiektu tworzy obiekt do prototypu:
instanceof
Operator należy unikać, ponieważ podróbki klas, które nie istnieją w JavaScript. Pomimo tegoclass
słowa kluczowego nie w ES2015, ponieważclass
jest to po prostu cukier składniowy dla ... ale to inna historia.źródło
instanceof
pochodzi odisPrototypeOf
. Nazywam ten cukier składniowy. A twoje źródło MDN to żart, prawda?instanceof
nie robię tego samego, coisPrototypeOf
. Otóż to.Właśnie znalazłem aplikację z prawdziwego świata i myślę, że teraz będzie z niej częściej korzystać.
Jeśli używasz zdarzeń jQuery, czasami chcesz napisać bardziej ogólną funkcję, która może być również wywoływana bezpośrednio (bez zdarzenia). Możesz użyć,
instanceof
aby sprawdzić, czy pierwszy parametr funkcji jest instancjąjQuery.Event
i odpowiednio zareagować.W moim przypadku funkcja potrzebowała obliczyć coś dla wszystkich (poprzez zdarzenie kliknięcia na przycisku) lub tylko dla jednego określonego elementu. Kod, którego użyłem:
źródło