Najczęstsze pytania dotyczące SmooshGate

Co się stało z smoosh?!

Propozycja funkcji języka JavaScript o nazwie Array.prototype.flatten okazuje się niekompatybilna z internetem. Udostępnienie tej funkcji w Firefoksie Nightly spowodowało awarię co najmniej jednej popularnej strony. Ponieważ problematyczny kod jest częścią szeroko zakrojonej biblioteki MooTools, może on dotyczyć większej liczby witryn. (Chociaż w 2018 r. narzędzie MooTools nie jest powszechnie stosowane w nowych witrynach, było bardzo popularne, ale jest wciąż dostępne na wielu stronach poświęconych produkcjom).

Autor oferty pakietowej żartobliwie zaproponował zmianę nazwy z: flatten na smoosh, aby uniknąć problemu ze zgodnością. Dowcip nie był dla wszystkich jasny, niektórzy zaczęli błędnie sądzić, że nowa nazwa została już wymyślona, i sprawa szybko się rozwinęła.

Co robi Array.prototype.flatten?

Array.prototype.flat, pierwotnie zaproponowany jako Array.prototype.flatten, płaskie tablice rekurencyjnie do określonego zakresu depth, którego wartość domyślna to 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, który jest podobny do 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 ma własną niestandardową wersję Array.prototype.flatten:

Array.prototype.flatten = /* non-standard implementation */;

Implementacja flatten narzędzia MooTools różni się od proponowanego standardu. Jednak to nie jest problem. Gdy przeglądarki wysyłają kod Array.prototype.flatten natywnie, MooTools zastępuje implementację natywną. Dzięki temu kod bazujący na działaniu MooTools działa zgodnie z oczekiwaniami niezależnie od tego, czy jest dostępna natywna funkcja flatten. Idzie Ci doskonale!

Niestety dzieje się coś innego. MooTools kopiuje wszystkie swoje metody tablicy niestandardowego do funkcji Elements.prototype (gdzie Elements to interfejs API specyficzny dla MooTools):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

Powtarzanie forin właściwości „enumerable”, które nie obejmują metod natywnych, takich jak Array.prototype.sort, ale obejmują regularnie przypisane właściwości, takie jak Array.prototype.foo = whatever. Pamiętaj jednak, że jeśli nadpiszesz niezliczoną właściwość, np. Array.prototype.sort = whatever, pozostaje ona niewymierna.

Obecnie Array.prototype.flatten = mooToolsFlattenImplementation tworzy zliczaną właściwość flatten, więc jest później kopiowana do usługi Elements. Jeśli jednak przeglądarki wysyłają natywną wersję elementu flatten, staje się ona nieliczna i nie jest kopiowana do Elements. Kod, który korzysta z narzędzi Elements.prototype.flatten z MooTools, jest teraz uszkodzony.

Wydaje się, że zmiana natywnej funkcji Array.prototype.flatten tak, by była liczna, rozwiązałaby problem, ale spowodowałoby to jeszcze większe problemy ze zgodnością. Każda witryna używająca elementów typu forin do iteracji w ramach tablicy (co jest niewłaściwą praktyką, ale się zdarza), wówczas nagle generuje dodatkową pętlę dla właściwości flatten.

Większym problemem jest modyfikowanie obiektów wbudowanych. Rozwijanie prototypów natywnych jest obecnie ogólnie uznawane za niewłaściwą praktykę, ponieważ nie komponuje się ono ładnie z innymi bibliotekami i kodem innych firm. Nie modyfikuj obiektów, które nie należą do Ciebie.

Dlaczego nie zachowamy dotychczasowej nazwy i nie łamiemy internetu?

W 1996 r., zanim rozpowszechniono CSS, i na długo zanim „HTML5” stał się powszechnie używany, strona internetowa Space Jam została opublikowana. Dziś witryna działa tak jak 22 lata temu.

Jak do tego doszło? Czy ktoś utrzymuje witrynę przez te wszystkie lata i aktualizuje ją za każdym razem, gdy dostawca przeglądarek wprowadzał nową funkcję?

Okazuje się, że „nie naruszaj sieci” to główna zasada projektowania w HTML, CSS, JavaScript i innych standardach powszechnie stosowanych w internecie. Jeśli udostępnienie nowej funkcji przeglądarki spowoduje, że istniejące witryny przestaną działać, ma to szkodę dla wszystkich:

  • użytkownicy witryny, której dotyczy problem, nagle poczuli się nieswojo;
  • właściciel witryny zmienił ją z idealnie działającej witryny na niedziałającą.
  • dostawcy przeglądarek, którzy dostarczają nową funkcję, tracą udział w rynku, ponieważ użytkownicy przechodzą na inną przeglądarkę po tym, gdy zauważą, że „działa ona w przeglądarce X”;
  • jeśli znany jest problem ze zgodnością, inni dostawcy przeglądarek odmawiają jego dostarczenia. Specyfikacja cech nie odpowiada rzeczywistości („tylko dzieło fikcyjne”), co ma negatywny wpływ na proces standaryzacji.

Wydaje mi się, że wsteczem narzędzie MooTools popełniło niewłaściwą sytuację – ale rozbicie sieci niczego nie karze, tylko karze użytkowników. Ci użytkownicy nie wiedzą, czym jest narzędzie moo. Możemy też znaleźć inne rozwiązanie, które pozwoli użytkownikom nadal korzystać z sieci. Wybór jest prosty.

Czy to oznacza, że nieprawidłowych interfejsów API nie można nigdy usunąć z platformy sieciowej?

To zależy. W rzadkich przypadkach możemy usunąć nieprawidłowe funkcje z internetu. Samo ustalenie, czy można usunąć jakąś cechę, nie jest łatwe. Do określenia liczby stron internetowych, których działanie w związku z tym zostanie zmienionych, konieczne jest zastosowanie obszernych danych telemetrycznych. Można to jednak zrobić, gdy funkcja nie jest wystarczająco bezpieczna, szkodliwa dla użytkowników lub używana bardzo rzadko.

<applet>, <keygen> i showModalDialog() to przykłady nieprawidłowych interfejsów API, które zostały usunięte z platformy internetowej.

Dlaczego nie naprawimy po prostu narzędzi MooTools?

Dobrym pomysłem jest poprawienie narzędzi MooTools tak, aby nie rozszerzały już wbudowanych obiektów. To nie rozwiąże jednak bieżącego problemu. Nawet jeśli MooTools udostępni wersję z poprawką, wszystkie istniejące witryny, które z niej korzystają, musiałyby zaktualizować się w celu wyeliminowania problemu ze zgodnością.

Czy użytkownicy nie mogą po prostu zaktualizować swojej kopii narzędzi MooTools?

W idealnym świecie MooTools opublikował poprawkę, a każda witryna korzystająca z MooTools magicznie zaktualizowana następnego dnia. Problem rozwiązany, prawda?!

Jest to niestety nierealistyczne. Nawet jeśli ktoś w jakiś sposób określiłby pełny zbiór witryn, których dotyczy ten problem, zdołałby znaleźć dane kontaktowe każdej z nich, skutecznie skontaktować się ze wszystkimi właścicielami witryny i przekonać ich do przeprowadzenia aktualizacji (co może oznaczać refaktoryzację całej bazy kodu), a cały proces mógłby zająć całe lata.

Pamiętaj, że wiele z tych witryn jest nieaktualnych i prawdopodobnie nie były obsługiwane. Nawet jeśli właściciel jest nadal obecny, prawdopodobnie nie jest tak wybitnym programistą stron internetowych jak Ty. Nie wszyscy muszą zmienić 8-letnią witrynę z powodu problemów ze zgodnością z internetem.

Jak działa proces TC39?

TC39 to komitet odpowiedzialny za rozwijanie języka JavaScript w oparciu o standard ECMAScript.

Niektórzy użytkownicy #SmooshGate myśleli, że „TC39 chce zmienić nazwę flatten na smoosh”, ale był to żart, który nie został dobrze przekazany z zewnątrz. Istotne decyzje, takie jak zmiana nazwy oferty, nie są podejmowane pochopnie, nie są podejmowane przez jedną osobę i na pewno nie są podejmowane z dnia na dzień na podstawie pojedynczego komentarza na GitHubie.

Proponowane funkcje w ramach TC39 opierają się na przejrzystym procesie testowania. Propozycje ECMAScript i wszelkie ich istotne zmiany (w tym zmiany metod) są omawiane podczas spotkań TC39 i muszą zostać zatwierdzone przez cały komitet, zanim staną się oficjalne. W przypadku usługi Array.prototype.flatten oferta przeszła już kilka etapów uzgadniania szczegółów aż do etapu 3, co oznacza, że tę funkcję można już wdrożyć w przeglądarkach. Podczas wdrażania mogą pojawiać się dodatkowe problemy ze specyfikacjami. W tym przypadku najważniejsza opinia przychodzi po próbie jej wysłania: funkcja w obecnym stanie przełamuje sieć. Trudne do przewidzenia problemy sprawiają, że proces TC39 nie kończy się wraz z wprowadzeniem funkcji przez przeglądarki.

TC39 działa na zasadzie konsensusu, co oznacza, że komisja musi uzgadniać wszystkie nowe zmiany. Nawet jeśli nazwa smoosh była poważną sugestią, prawdopodobnie któryś z członków komisji sprzeciwił się jej i oferował powszechną nazwę, taką jak compact lub chain.

Zmiana nazwy z flatten na smoosh (nawet jeśli nie była to żart) nie była jeszcze omawiana na spotkaniu TC39. W związku z tym oficjalne stanowisko TC39 w tej kwestii jest obecnie nieznane. Żadna osoba nie może wypowiadać się w imieniu wszystkich TC39, dopóki nie osiągniecie porozumienia na następnym spotkaniu.

W spotkaniach TC39 biorą udział osoby o bardzo różnym wykształceniu: niektórzy z nich mają wieloletnie doświadczenie w projektowaniu języka programowania, inni pracują w przeglądarce lub mechanizmie JavaScript, a wraz z rosnącą liczbą uczestników reprezentować społeczność programistów JavaScriptu.

Jak ostatecznie rozwiązano SmooshGate?

Podczas spotkania TC39, które odbyło się w maju 2018 r., działanie #SmooshGate zostało oficjalnie usunięte, zmieniając nazwę flatten na flat.

Array.prototype.flat i Array.prototype.flatMap są dostarczane w wersji 8 w wersji 6.9 i Chrome 69.