Apa yang terjadi smoosh?!
Proposal untuk fitur bahasa
JavaScript yang disebut Array.prototype.flatten
ternyata
tidak kompatibel dengan Web. Pengiriman fitur di Firefox Nightly menyebabkan setidaknya satu situs populer rusak. Mengingat kode yang bermasalah adalah bagian dari library MooTools
yang tersebar luas, kemungkinan ada lebih banyak situs yang terpengaruh. (Meskipun MooTools
tidak umum digunakan untuk situs baru pada tahun 2018, MooTools dulu sangat populer dan
masih ada di banyak situs produksi.)
Penulis proposal dengan bercanda menyarankan untuk mengganti nama flatten
menjadi smoosh
untuk
menghindari masalah kompatibilitas. Lelucon itu tidak jelas bagi semua orang, beberapa
orang mulai salah meyakini bahwa nama baru telah
diputuskan, dan segala sesuatunya menjadi makin cepat.
Apa yang dilakukan Array.prototype.flatten
?
Array.prototype.flat
, yang awalnya diusulkan sebagai Array.prototype.flatten
, akan meratakan array secara rekursif hingga depth
yang ditentukan, yang secara default ditetapkan ke 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]
Proposal yang sama mencakup Array.prototype.flatMap
, yang mirip dengan
Array.prototype.map
, kecuali bahwa Array.prototype.flatMap
meratakan hasilnya ke dalam array baru.
[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]
Apa yang dilakukan MooTools yang menyebabkan masalah ini?
MooTools menentukan versi Array.prototype.flatten
non-standarnya sendiri:
Array.prototype.flatten = /* non-standard implementation */;
Implementasi flatten
MooTools berbeda dari standar yang diusulkan.
Namun, ini bukan masalahnya. Saat browser mengirimkan
Array.prototype.flatten
secara native, MooTools akan mengganti penerapan
native. Hal ini memastikan bahwa kode yang mengandalkan perilaku MooTools
berfungsi seperti yang diinginkan, terlepas dari apakah flatten
native tersedia atau tidak.
Sejauh ini, hasilnya bagus.
Sayangnya, hal lain kemudian terjadi. MooTools menyalin semua
metode array kustomnya ke Elements.prototype
(dengan Elements
adalah
API khusus MooTools):
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
for
-in
melakukan iterasi pada properti “yang dapat dihitung”, yang tidak menyertakan
metode native seperti Array.prototype.sort
, tetapi menyertakan
properti yang ditetapkan secara rutin seperti Array.prototype.foo = whatever
. Namun,
dan inilah intinya — jika Anda menimpa properti yang tidak dapat di-enumerasi, misalnya
Array.prototype.sort = whatever
, properti tersebut tetap tidak dapat di-enumerasi.
Saat ini, Array.prototype.flatten = mooToolsFlattenImplementation
membuat
properti flatten
yang dapat dihitung, sehingga nanti disalin ke Elements
. Namun, jika browser mengirimkan flatten
versi native, flatten
menjadi tidak dapat dihitung, dan tidak disalin ke Elements
. Kode apa pun yang mengandalkan Elements.prototype.flatten
MooTools kini rusak.
Meskipun tampaknya mengubah Array.prototype.flatten
native menjadi
dapat dihitung akan memperbaiki masalah, tindakan ini kemungkinan akan menyebabkan lebih banyak
masalah kompatibilitas. Setiap situs yang mengandalkan for
-in
untuk melakukan iterasi pada array (yang merupakan praktik buruk, tetapi hal ini terjadi) akan tiba-tiba mendapatkan iterasi loop tambahan untuk properti flatten
.
Masalah mendasar yang lebih besar di sini adalah mengubah objek bawaan. Memperluas prototype native saat ini umumnya dianggap sebagai praktik yang buruk, karena tidak berkomponen dengan baik dengan library lain dan kode pihak ketiga. Jangan ubah objek yang bukan milik Anda.
Mengapa kita tidak mempertahankan nama yang ada dan merusak Web?
Pada tahun 1996, sebelum CSS tersebar luas, dan jauh sebelum “HTML5” menjadi hal yang umum, situs Space Jam diluncurkan. Saat ini, situs tersebut masih berfungsi dengan cara yang sama seperti 22 tahun yang lalu.
Bagaimana hal itu bisa terjadi? Apakah ada seseorang yang mengelola situs tersebut selama bertahun-tahun, dan memperbaruinya setiap kali vendor browser merilis fitur baru?
Ternyata, “jangan merusak Web” adalah prinsip desain nomor satu untuk HTML, CSS, JavaScript, dan standar lainnya yang banyak digunakan di Web. Jika fitur browser baru yang dikirimkan menyebabkan situs yang ada berhenti berfungsi, hal ini akan merugikan semua orang:
- pengunjung situs web yang terpengaruh tiba-tiba mengalami kerusakan pengalaman pengguna;
- pemilik situs berubah dari memiliki situs yang berfungsi dengan sempurna menjadi situs yang tidak berfungsi tanpa mengubah apa pun;
- Vendor browser yang mengirimkan fitur baru kehilangan pangsa pasar, karena pengguna beralih browser setelah melihat "fungsi ini berfungsi di browser X";
- jika masalah kompatibilitas diketahui, vendor browser lain menolak untuk mengirimkannya. Spesifikasi fitur tidak sesuai dengan kenyataan (“hanya karya fiksi”), yang buruk untuk proses standardisasi.
Tentu saja, jika dipikir-pikir, MooTools melakukan hal yang salah — tetapi merusak web tidak menghukum mereka, melainkan menghukum pengguna. Pengguna ini tidak tahu apa itu alat moo. Atau, kita dapat menemukan solusi lain, dan pengguna dapat terus menggunakan web. Pilihannya mudah dibuat.
Apakah itu berarti API yang buruk tidak akan pernah dihapus dari Platform Web?
Tergantung. Dalam kasus yang jarang terjadi, fitur buruk dapat dihapus dari Web. Bahkan hanya mengetahui apakah mungkin untuk menghapus fitur adalah upaya yang sangat rumit, yang memerlukan telemetri yang luas untuk mengukur berapa banyak halaman web yang perilakunya akan diubah. Namun, jika fitur tersebut tidak cukup aman, berbahaya bagi pengguna, atau jarang digunakan, hal ini dapat dilakukan.
<applet>
, <keygen>
, dan
showModalDialog()
adalah
contoh API buruk yang berhasil dihapus dari Web Platform.
Mengapa kita tidak memperbaiki MooTools saja?
Melakukan patch pada MooTools agar tidak lagi memperluas objek bawaan adalah ide yang baik. Namun, hal tersebut tidak menyelesaikan masalah yang dihadapi. Meskipun MooTools akan merilis versi yang di-patch, semua situs yang ada yang menggunakannya harus diupdate agar masalah kompatibilitas hilang.
Tidak bisakah orang cukup memperbarui salinan MooTools mereka?
Dalam dunia yang sempurna, MooTools akan merilis patch, dan setiap situs yang menggunakan MooTools akan otomatis diupdate keesokan harinya. Masalahnya selesai, bukan?
Sayangnya, hal ini tidak realistis. Meskipun seseorang berhasil mengidentifikasi seluruh situs yang terpengaruh, menemukan informasi kontak untuk setiap situs, berhasil menghubungi semua pemilik situs, dan meyakinkan mereka semua untuk melakukan update (yang mungkin berarti memfaktorkan ulang seluruh codebase mereka), seluruh prosesnya akan memakan waktu bertahun-tahun.
Perlu diingat bahwa banyak situs ini sudah lama dan mungkin tidak dikelola. Meskipun pengelola masih ada, mungkin ia bukan developer web yang sangat terampil seperti Anda. Kita tidak dapat mengharapkan semua orang untuk mengubah situs mereka yang sudah berusia 8 tahun karena masalah kompatibilitas web.
Bagaimana cara kerja proses TC39?
TC39 adalah komite yang bertanggung jawab mengembangkan bahasa JavaScript melalui standar ECMAScript.
#SmooshGate membuat beberapa orang percaya bahwa “TC39 ingin mengganti nama flatten
menjadi
smoosh
”, tetapi itu adalah lelucon yang tidak dikomunikasikan dengan baik secara eksternal.
Keputusan besar seperti mengganti nama proposal tidak diambil dengan mudah, tidak diambil
oleh satu orang, dan pastinya tidak diambil dalam semalam berdasarkan satu
komentar GitHub.
TC39 beroperasi pada proses staging yang jelas untuk proposal fitur.
Proposal ECMAScript dan perubahan besar apa pun pada proposal tersebut (termasuk
penggantian nama metode) dibahas selama rapat TC39, dan perlu disetujui oleh
seluruh komite sebelum menjadi resmi. Dalam kasus
Array.prototype.flatten
, proposal telah melalui beberapa
tahap persetujuan, hingga Tahap 3, yang menunjukkan bahwa fitur tersebut
siap diterapkan di browser Web. Masalah spesifikasi tambahan
biasanya muncul selama penerapan. Dalam hal ini, masukan
yang paling penting datang setelah mencoba mengirimkannya: fitur, dalam statusnya saat ini,
merusak Web. Masalah yang sulit diprediksi seperti ini adalah salah satu alasan mengapa
proses TC39 tidak hanya berakhir setelah browser mengirimkan fitur.
TC39 beroperasi berdasarkan konsensus, yang berarti komite harus menyetujui setiap perubahan
baru. Meskipun smoosh
adalah saran yang serius, sepertinya anggota komite akan menolaknya dan memberikan nama yang lebih umum seperti compact
atau chain
.
Penggantian nama dari flatten
menjadi smoosh
(meskipun bukan lelucon) belum pernah dibahas dalam rapat TC39. Dengan demikian, sikap resmi TC39 tentang
topik ini saat ini tidak diketahui. Tidak ada satu orang pun yang dapat berbicara atas nama
semua TC39 hingga konsensus tercapai pada rapat berikutnya.
Rapat TC39 umumnya dihadiri oleh orang-orang dengan latar belakang yang sangat beragam: beberapa memiliki pengalaman desain bahasa pemrograman selama bertahun-tahun, yang lain bekerja di browser atau mesin JavaScript, dan semakin banyak peserta yang hadir untuk mewakili komunitas developer JavaScript.
Bagaimana akhirnya SmooshGate diselesaikan?
Selama rapat TC39 Mei 2018, #SmooshGate
resmi diselesaikan dengan mengganti nama flatten
menjadi flat
.
Array.prototype.flat
dan Array.prototype.flatMap
dikirimkan di V8 v6.9 dan
Chrome 69.