Muszę przeprowadzić jakiś eksperyment i muszę znać jakiś unikalny identyfikator obiektów w javascript, żeby sprawdzić, czy są takie same. Nie chcę używać operatorów równości, potrzebuję czegoś takiego jak funkcja id () w Pythonie.
Czy coś takiego istnieje?
javascript
Stefano Borini
źródło
źródło
Odpowiedzi:
Zaktualizuj Moja oryginalna odpowiedź poniżej została napisana 6 lat temu w stylu stosownym do czasów i mojego zrozumienia. W odpowiedzi na pewną rozmowę w komentarzach, bardziej nowoczesne podejście do tego jest następujące:
Jeśli masz archaiczne wymagania dotyczące przeglądarki, sprawdź tutaj zgodność przeglądarki
Object.defineProperty
.Oryginalna odpowiedź jest przechowywana poniżej (zamiast tylko w historii zmian), ponieważ uważam, że porównanie jest wartościowe.
Możesz dać następujący obrót. Daje to również opcję jawnego ustawienia identyfikatora obiektu w jego konstruktorze lub w innym miejscu.
Uważaj, aby upewnić się, że członek, którego używasz do wewnętrznego przechowywania unikalnego identyfikatora, nie koliduje z inną automatycznie utworzoną nazwą członka.
źródło
object.hasOwnProperty(member)
podczas korzystania zfor..in
pętli. Jest to dobrze udokumentowana praktyka, którą egzekwuje jslintdefineProperty(…, {enumerable:false})
. I takuid
sama metoda powinna znajdować się wObject
przestrzeni nazw4
jak przypiszesz obiekt o identyfikatorze 4 do zmiennej, abyś mógł z nią robić rzeczy ... na przykład uzyskać dostęp do jej właściwości?Jeśli chodzi o moje obserwacje, każda zamieszczona tutaj odpowiedź może mieć nieoczekiwane skutki uboczne.
W środowisku zgodnym z ES2015 możesz uniknąć skutków ubocznych, używając WeakMap .
źródło
return currentId
?WeakMap
w przeciwieństwie doMap
? Ta funkcja ulegnie awarii, jeśli podasz jej ciąg lub liczbę.Najnowsze przeglądarki zapewniają czystszą metodę rozszerzania Object.prototype. Ten kod spowoduje, że właściwość będzie ukryta przed wyliczeniem właściwości (dla p in o)
W przypadku przeglądarek, które implementują defineProperty , możesz zaimplementować właściwość uniqueId w następujący sposób:
Aby uzyskać szczegółowe informacje, zobacz https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
źródło
Właściwie nie musisz modyfikować
object
prototypu i dodawać tam funkcji. Poniższe działania powinny dobrze działać w Twoim celu.źródło
object
hacki. musisz go uruchamiać tylko wtedy, gdy chcesz dopasować obiekt OP i pozostaje on na uboczu przez resztę czasu.W przypadku przeglądarek implementujących tę
Object.defineProperty()
metodę poniższy kod generuje i zwraca funkcję, którą można powiązać z dowolnym posiadanym obiektem.Takie podejście ma tę zaletę, że nie rozszerza się
Object.prototype
.Kod działa, sprawdzając, czy dany obiekt ma
__objectID__
właściwość, a jeśli tak nie jest , definiując go jako ukrytą (niewliczalną) właściwość tylko do odczytu.Jest więc bezpieczny przed jakąkolwiek próbą zmiany lub przedefiniowania
obj.__objectID__
właściwości tylko do odczytu po jej zdefiniowaniu i konsekwentnie generuje ładny błąd zamiast cichego niepowodzenia.Wreszcie, w dość skrajnym przypadku, gdy jakiś inny kod byłby już zdefiniowany
__objectID__
na danym obiekcie, ta wartość zostanie po prostu zwrócona.źródło
Kod jQuery używa własnej
data()
metody jako takiego identyfikatora.Na zapleczu metoda
data
tworzy bardzo specjalne pole oobject
nazwie"jQuery" + now()
put tam next id strumienia unikalnych identyfikatorów, takich jakSugerowałbym, abyś użył tej samej metody, ponieważ John Resig oczywiście wie wszystko o JavaScript, a jego metoda opiera się na całej tej wiedzy.
źródło
data
Metoda jQuery ma wady. Zobacz na przykład stackoverflow.com/questions/1915341/… . Poza tym John Resig w żadnym wypadku nie wie wszystkiego, co trzeba wiedzieć o JavaScript, a przekonanie, że to nie pomoże, jako programista JavaScript.Wersja @justin answer zgodna z ES6 na maszynie, wykorzystująca symbole, aby zapobiec kolizji kluczy i dodana dla wygody do globalnego Object.id. Po prostu skopiuj, wklej poniższy kod lub umieść go w pliku ObjecId.ts, który zaimportujesz.
Przykład użycia:
źródło
Użyłem takiego kodu, który spowoduje, że Objects będzie ciągnąć za pomocą unikalnych ciągów:
te
__proto__
bity są zachować__id__
getter od pojawiać się w obiekcie. zostało to przetestowane tylko w przeglądarce Firefox.źródło
__defineGetter__
jest to niestandardowe.Pomimo porady, aby nie modyfikować Object.prototype, może to być naprawdę przydatne do testowania w ograniczonym zakresie. Autor zaakceptowanej odpowiedzi zmienił ją, ale nadal ustala
Object.id
, co nie ma dla mnie sensu. Oto fragment, który spełnia swoje zadanie:źródło
Napotkałem ten sam problem i oto rozwiązanie, które zaimplementowałem w ES6
źródło
W celu porównania dwóch obiektów najprostszym sposobem byłoby dodanie unikalnej właściwości do jednego z obiektów w momencie, gdy trzeba porównać obiekty, sprawdzenie, czy właściwość istnieje w drugim, a następnie ponowne jej usunięcie. Oszczędza to zastępowanie prototypów.
źródło