Perfekcyjny jest również powodem. Czasami może być konieczne zapętlenie kluczy. Można to zrobić na kilka sposobów
for (let key in object) { ... }
for (let key in object) { if (object.hasOwnProperty(key) { ... } }
for (let key of Object.keys(object)) { ... }
Zwykle używam, for of Object.keys()
ponieważ robi to dobrze i jest stosunkowo zwięzły, nie ma potrzeby dodawania czeku.
Ale jest znacznie wolniejszy .
Zgadywanie, że powód Object.keys
jest powolny, jest oczywiste, Object.keys()
trzeba dokonać alokacji. W rzeczywistości AFAIK musi przydzielić kopię wszystkich kluczy od tego czasu.
const before = Object.keys(object);
object.newProp = true;
const after = Object.keys(object);
before.join('') !== after.join('')
Możliwe, że silnik JS mógłby użyć jakiejś niezmiennej struktury klucza, aby zwrócić Object.keys(object)
odniesienie coś, co iteruje po niezmiennych kluczach i object.newProp
tworzy całkowicie nowy niezmienny obiekt kluczy, ale cokolwiek, jest wyraźnie wolniejsze nawet 15x
Nawet sprawdzanie hasOwnProperty
jest do 2x wolniejsze.
Chodzi o to, że jeśli masz kod wrażliwy na perfekcję i potrzebujesz pętli po klawiszach, chcesz mieć możliwość korzystania z niego for in
bez konieczności dzwonienia hasOwnProperty
. Możesz to zrobić tylko wtedy, gdy nie dokonałeś modyfikacjiObject.prototype
zwróć uwagę, że jeśli Object.defineProperty
zmodyfikujesz prototyp, jeśli dodasz elementy, których nie da się wyliczyć, nie wpłyną one na zachowanie JavaScript w powyższych przypadkach. Niestety, przynajmniej w Chrome 83 wpływają one na wydajność.
Dodałem 3000 niewliczalnych właściwości, aby wymusić pojawienie się jakichkolwiek problemów z perfekcją. Przy zaledwie 30 właściwościach testy były zbyt bliskie, aby stwierdzić, czy wystąpił jakikolwiek wpływ na wydajność.
https://jsperf.com/does-adding-non-enumerable-properties-affect-perf
Firefox 77 i Safari 13.1 nie wykazały żadnej różnicy w wydajności między klasami rozszerzonymi i nieugmentowanymi, być może wersja 8 zostanie naprawiona w tym obszarze i możesz zignorować problemy z perf.
Ale dodam też, że istnieje historiaArray.prototype.smoosh
. Krótka wersja to Mootools, popularna biblioteka, stworzona we własnym zakresie Array.prototype.flatten
. Kiedy komitet normalizacyjny próbował dodać rodzimego Array.prototype.flatten
, okazało się, że nie jest to możliwe bez niszczenia wielu witryn. Twórcy, którzy dowiedzieli się o przerwie, zasugerowali nazwanie metody es5 smoosh
żartem, ale ludzie przestraszyli się, nie rozumiejąc, że to żart. flat
Zamiast tego zdecydowali sięflatten
Morał z tej historii jest taki, że nie powinieneś rozszerzać rodzimych obiektów. Jeśli to zrobisz, możesz napotkać ten sam problem z psuciem się plików i jeśli Twoja konkretna biblioteka nie będzie tak popularna jak MooTools, dostawcy przeglądarek raczej nie obejdą problemu, który spowodowałeś. Jeśli Twoja biblioteka stanie się tak popularna, byłoby to w pewnym sensie wymuszenie na wszystkich innych rozwiązaniu problemu, który spowodowałeś. Dlatego proszę nie rozszerzać natywnych obiektów