Co się stało smoosh?!
Oferta pakietowa JavaScript
funkcja językowa Array.prototype.flatten
okazała się
Niezgodność z internetem. Wysyłka tej funkcji w przeglądarce Firefox Nightly spowodowała co najmniej 1 popularną witrynę
do złamania. Biorąc pod uwagę, że problematyczny kod jest częścią powszechnych narzędzi MooTools
problem może dotyczyć wielu innych witryn. (Mimo że MooTools
nie jest powszechnie wykorzystywane w nowych witrynach w 2018 r., ale cieszył się wtedy dużą popularnością.
wciąż jest dostępny w wielu witrynach produkcyjnych).
Autor oferty pakietowej żartobliwie zaproponował zmianę nazwy „flatten
” na „smoosh
” na
uniknąć problemów ze zgodnością. Dla niektórych żart nie był zrozumiały.
ludzie zaczęli błędnie sądzić, że nowa nazwa została już
i szybko się zaczęło.
Co robi Array.prototype.flatten
?
Array.prototype.flat
, pierwotnie proponowany jako Array.prototype.flatten
,
rekurencyjnie spłaszcza tablice aż do określonego parametru depth
, który jest wartością domyślną
do 1
.
// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]
// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]
Ta sama oferta pakietowa zawiera element Array.prototype.flatMap
, czyli
Array.prototype.map
, tyle że spłaszcza wynik do nowej tablicy.
[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]
Co powoduje ten problem?
MooTools definiuje własną niestandardową wersję Array.prototype.flatten
:
Array.prototype.flatten = /* non-standard implementation */;
Implementacja flatten
w MooTools różni się od proponowanego standardu.
Nie na tym jednak polega problem. Kiedy przeglądarki są wysyłane
Array.prototype.flatten
natywnie, MooTools zastępuje wersję natywną
implementacji. Dzięki temu kod bazujący na działaniu narzędzi MooTools
działa zgodnie z oczekiwaniami niezależnie od tego, czy natywna usługa flatten
jest dostępna.
Idzie Ci doskonale!
Niestety dzieje się potem coś innego. Narzędzie MooTools skopiuje
niestandardowe metody tablic do Elements.prototype
(gdzie Elements
to
interfejsu API MooTools):
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
Parametr for
-in
wykona iterację względem właściwości „enumerable”, które nie obejmują
metod natywnych takich jak Array.prototype.sort
, ale uwzględnia
regularnie przypisanych właściwości, takich jak Array.prototype.foo = whatever
. Ale...
a oto wstęp – jeśli zastąpisz właściwość niemożliwą do wyliczenia, np.
Array.prototype.sort = whatever
, pozostaje niewyliczana.
Obecnie Array.prototype.flatten = mooToolsFlattenImplementation
tworzy
wyliczaną właściwość flatten
, więc zostaje ona później skopiowana do funkcji Elements
. Ale jeśli
przeglądarki wysyłają natywną wersję systemu flatten
, staje się ona niewyliczana,
nie jest kopiowany do obszaru Elements
. Dowolny kod oparty na narzędziach MooTools
Numer Elements.prototype.flatten
nie działa.
Wydaje się, że trzeba zmienić natywny Array.prototype.flatten
na
rozwiązania Enumerable rozwiązałyby problem, prawdopodobnie doprowadziłoby do jeszcze
problemy ze zgodnością. Wszystkie witryny, które wymagają iteracji (for
–in
)
tablica (co nie jest dobrą praktyką, ale się zdarza), wówczas nagle otrzyma
dodatkową pętlę dla właściwości flatten
.
Głównym problemem jest tu modyfikacja obiektów wbudowanych. Przedłużam prototypy natywne są obecnie powszechnie akceptowane, ponieważ nie komponuje się dobrze z innymi bibliotekami i kodem innych firm. Nie zmieniaj obiektów, których nie jesteś właścicielem.
Dlaczego nie zostawimy istniejącej nazwy i przełamania internetu?
W 1996 roku, zanim CSS zaczęła się rozpowszechniać, i na długo zanim „HTML5” stał się opublikowaliśmy stronę Space Jam. Strona nadal działa tak jak 22 lata temu.
Jak do tego doszło? Czy ktoś przez te wszystkie lata prowadził tę witrynę, aktualizować go za każdym razem, gdy dostawcy przeglądarek udostępnili nową funkcję?
Okazuje się, że „nie łamać internetu” to najważniejsza zasada projektowania. dla HTML, CSS, JavaScript i innych standardów powszechnie używanych Sieć. Jeśli wysłanie nowej funkcji przeglądarki powoduje przerwanie działania istniejących witryn działa, co jest szkodliwe dla wszystkich:
- użytkownicy witryn, których dotyczy problem, nagle odczuwają niezadowolenie;
- a właściciele witryn – od idealnie działającej witryny niedziałające bez żadnych zmian;
- dostawcy przeglądarek, którzy dostarczają nową funkcję, tracą udział w rynku, ponieważ użytkownicy przełączać przeglądarki po zauważeniu, że działa w przeglądarce X;
- gdy będzie znany problem ze zgodnością, inni dostawcy przeglądarek odmówią . Specyfikacja funkcji nie jest zgodna z rzeczywistością („ nic poza fikcją”), co niekorzystnie wpływa na proces standaryzacji.
Oczywiście, według najnowszych informacji MooTools zrobił błąd – ale zniszczyła sieć że nie karze, a jedynie użytkowników. Ci użytkownicy nie wiedzą, co to mu0 . Możemy też znaleźć inne rozwiązanie, a użytkownicy mogą kontynuować do korzystania z sieci. Wybór jest prosty.
Czy to oznacza, że złych interfejsów API nie można nigdy usunąć z platformy internetowej?
To zależy. W rzadkich przypadkach nieprawidłowe funkcje mogą zostać usunięte z internetu. Nawet gdy zastanawiam się, czy możliwe usunięcie jakiejś funkcji jest bardzo trudne, wymagają obszernych danych telemetrycznych, aby oszacować, ile stron internetowych zachowanie użytkownika. Jeśli jednak funkcja jest wystarczająco niebezpieczna, jest szkodliwa użytkowników lub jest używany bardzo rzadko.
<applet>
, <keygen>
i
showModalDialog()
to wszystkie
przykłady nieprawidłowych interfejsów API, które zostały usunięte z platformy internetowej.
Dlaczego nie naprawiamy po prostu narzędzi MooTools?
Poprawienie narzędzi MooTools tak, aby nie rozszerzały już wbudowanych obiektów, i pomysłu. Nie rozwiązuje to jednak występującego problemu. Nawet jeśli MooNarzędzia były jeśli chcesz opublikować poprawkę, wszystkie istniejące witryny korzystające z tej wersji .
Czy nie można po prostu zaktualizować kopii narzędzi MooTools?
W idealnym świecie narzędzie Moo Tools publikowało poprawkę, a każda witryna które zostałyby zaktualizowane następnego dnia. Problem rozwiązany, prawda?
Jest to niestety nierealistyczne. Nawet gdyby ktoś mógł w jakiś sposób zidentyfikować wszystkich witryn, których dotyczy problem, znaleźć informacje kontaktowe dla skontaktować się z wszystkimi właścicielami witryn, i przekonać wszystkich do przeprowadzenia aktualizacji (co może wymagać refaktoryzacji, z całej bazy kodu), cały proces trwałby w najlepszym przypadku lat.
Pamiętaj, że wiele z nich jest starych i prawdopodobnie niedostosowanych. Nawet jeśli opiekun jest wciąż w pobliżu, możliwe, że nie Wysoko wykwalifikowanych programistów internetowych, takich jak Ty. Nie możemy oczekiwać, że wszyscy odejdą i zmienili 8-letnią witrynę z powodu problemu ze zgodnością.
Jak wygląda proces TC39?
TC39 to komitet odpowiedzialny za rozwijanie języka JavaScript standardu ECMAScript.
#SmooshGate sprawia, że niektórzy sądzą, że „TC39 chce zmienić nazwę domeny flatten
na
smoosh
”, ale był to żart, który nie był dobrze skomunikowany na zewnątrz.
Ważne decyzje, takie jak zmiana nazwy oferty, nie są podejmowane łatwo
na jeden dzień i na pewno nie zostaną zrobione z dnia na dzień na podstawie
Komentarz na GitHubie.
TC39 opiera się na przejrzystym procesie testowania propozycji funkcji.
propozycje ECMAScript i wszelkie istotne zmiany w nich (w tym metody
są omawiane podczas spotkań TC39 i muszą zostać zatwierdzone przez
komisji, zanim staną się oficjalne. W przypadku
Array.prototype.flatten
, oferta pakietowa została już sprawdzona
aż do etapu 3, który określa, że cecha
gotowe do wdrożenia w przeglądarkach. Często występuje w przypadku dodatkowych specyfikacji.
problemów podczas wdrażania. W tym przypadku najważniejszą kwestią
opinia została przesłana po próbie wysyłki: funkcja w obecnym stanie,
niszczy sieć. Niektóre trudne do przewidzenia problemy
Proces TC39 nie kończy się tylko w chwili udostępnienia funkcji przez przeglądarki.
TC39 opiera się na konsensusie, co oznacza, że komisja musi uzgodnić każdy nowy
zmian. Nawet jeśli smoosh
był dla mnie poważną sugestią, prawdopodobnie
członka komisji sprzeciwiałby się mu popularniejszej nazwie, np.
compact
lub chain
.
Zmiana nazwy z flatten
na smoosh
(nawet jeśli to nie był żart)
nigdy nie były omawiane na spotkaniu TC39. W związku z tym oficjalne stanowisko TC39 w sprawie
ten temat jest obecnie nieznany. Żadna osoba nie może wypowiadać się w imieniu użytkownika
w całym cyklu TC39 aż do osiągnięcia konsensusu na kolejnym spotkaniu.
W spotkaniach TC39 uczestniczą zwykle osoby o bardzo zróżnicowanych i doświadczeniem w projektowaniu w języku programowania, inne używają przeglądarki lub silnika JavaScript. Coraz więcej osób Reprezentują społeczność programistów JavaScript.
Jak ostatecznie rozwiązano SmooshGate?
Podczas spotkania TC39 w maju 2018 roku #SmooshGate
został oficjalnie rozwiązany przez zmianę nazwy z flatten
na flat
.
Array.prototype.flat
i Array.prototype.flatMap
zostały wysłane w wersji 8.9 oraz
Chrome 69.