Jeśli dobrze rozumiem, każdy obiekt w JavaScript dziedziczy po prototypie Object, co oznacza, że każdy obiekt w Javascript ma dostęp do funkcji hasOwnProperty poprzez swój łańcuch prototypów.
Podczas czytania kodu źródłowego require.js natknąłem się na tę funkcję:
function hasProp(obj, prop) {
return hasOwn.call(obj, prop);
}
hasOwn
jest odniesieniem do Object.prototype.hasOwnProperty
. Czy jest jakaś praktyczna różnica w zapisywaniu tej funkcji jako
function hasProp(obj, prop) {
return obj.hasOwnProperty(prop);
}
A skoro już o tym mowa, dlaczego w ogóle definiujemy tę funkcję? Czy jest to tylko kwestia skrótów i lokalnego buforowania dostępu do właściwości w celu (niewielkiego) wzrostu wydajności, czy też brakuje mi przypadków, w których hasOwnProperty może być używane na obiektach, które nie mają tej metody?
const hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
Może się to wydawać rozszczepianiem włosów, ale istnieje różnica między javascript (ogólny termin na implementacje ECMAScript) a ECMAScript (język używany do implementacji javascript). To ECMAScript definiuje schemat dziedziczenia, a nie javascript, więc tylko natywne obiekty ECMAScript muszą implementować ten schemat dziedziczenia.
Działający program javascript składa się przynajmniej z wbudowanych obiektów ECMAScript (obiekt, funkcja, liczba itp.) I prawdopodobnie z niektórych obiektów natywnych (np. Funkcji). Może również zawierać obiekty hosta (takie jak obiekty DOM w przeglądarce lub inne obiekty w innych środowiskach hostów).
Podczas gdy obiekty wbudowane i natywne muszą implementować schemat dziedziczenia zdefiniowany w ECMA-262, obiekty hosta tego nie robią. Dlatego nie wszystkie obiekty w środowisku javascript muszą dziedziczyć po Object.prototype . Na przykład obiekty hosta w IE zaimplementowane jako obiekty ActiveX będą generować błędy, jeśli będą traktowane jako obiekty natywne (dlatego try..catch jest używany do inicjowania obiektów MS XMLHttpRequest). Niektóre obiekty DOM (takie jak NodeLists w IE w trybie dziwactw), jeśli zostaną przekazane do metod Array, będą powodować błędy, obiekty DOM w IE 8 i niższych nie mają schematu dziedziczenia podobnego do ECMAScript, i tak dalej.
Dlatego nie należy zakładać, że wszystkie obiekty w środowisku javascript dziedziczą po Object.prototype.
Co nie jest prawdą w przypadku niektórych obiektów hosta w IE w trybie dziwactw (i IE 8 i niższych zawsze) przynajmniej.
Biorąc pod uwagę powyższe, warto zastanowić się, dlaczego obiekt może mieć własną metodę hasOwnProperty i celowość wywołania innej metody hasOwnProperty bez wcześniejszego sprawdzenia, czy jest to dobry pomysł, czy nie.
Edytować
Podejrzewam, że powodem używania
Object.prototype.hasOwnProperty.call
jest to, że w niektórych przeglądarkach obiekty hosta nie mają metody hasOwnProperty , użycie wywołania i wbudowana metoda jest alternatywą. Jednak zrobienie tego ogólnie nie wydaje się dobrym pomysłem z powodów wymienionych powyżej.Jeśli chodzi o obiekty hosta, operator in może być używany do testowania ogólnie właściwości, np
Alternatywa (przetestowana w IE6 i innych):
W ten sposób wywołujesz wbudowaną właściwość hasOwnProperty tylko wtedy, gdy obiekt jej nie ma (dziedziczony lub inny).
Jeśli jednak obiekt nie ma
hasOwnProperty
metody, prawdopodobnie równie dobrze jest użyć operatora in , ponieważ obiekt prawdopodobnie nie ma schematu dziedziczenia, a wszystkie właściwości są na obiekcie (to tylko założenie), np. operator in jest powszechnym (i pozornie skutecznym) sposobem testowania obsługi właściwości obiektów DOM.źródło
in
nie wyszukujehasOwnProperty()
, podejrzewam, że poszukiwana właściwość istniała w łańcuchu prototypów.hasOwnProperty
{"hasOwnProperty": 1}
Jeśli istnieje możliwość, że obiekt może mieć właściwość o tej nazwie, konieczne jest użycie zewnętrznej właściwości hasOwnProperty, aby uzyskać poprawne wyniki:
Możesz skopiować i wkleić poniższe fragmenty kodu do konsoli przeglądarki, aby uzyskać lepsze zrozumienie
Zawsze zwraca fałsz
Użyj właściwości hasOwnProperty innego obiektu i wywołaj ją z tym ustawieniem na foo
W tym celu można również użyć właściwości hasOwnProperty z prototypu Object
źródło
hasOwnProperty
zwrotówtrue
.Informacje podane w obu istniejących odpowiedziach są na miejscu. Jednak użycie:
pojawia się kilka razy. Należy zauważyć, że
hasOwnProperty
implementacje zwrócą wartość true tylko wtedy, gdy właściwość jest bezpośrednio zawarta w testowanym obiekcie.in
Operator poddadzą dół łańcucha prototypów zbyt.Oznacza to, że właściwości instancji zwrócą wartość true, gdy zostaną przekazane do
hasOwnProperty
miejsca, w którym właściwości prototypu zwrócą wartość false.Użycie
in
operatora zarówno właściwości instancji, jak i prototypu zwróci wartość true.źródło