Sorun neydi?
Array.prototype.flatten
adlı bir JavaScript dili özelliği için öneri, Web ile uyumlu değil. Özelliğin Firefox Nightly'de kullanıma sunulması en az bir popüler web sitesinin çalışmamasına neden oldu. Sorunlu kodun yaygın MooTools kitaplığının bir parçası olması nedeniyle, daha birçok web sitesinin etkilenmiş olması muhtemeldir. (MooTools, 2018'de yeni web siteleri için yaygın olarak kullanılmasa da eskiden çok popülerdi ve birçok üretim web sitesinde hâlâ kullanılıyor.)
Teklif yazarı, uyumluluk sorununu önlemek için şaka yoluyla flatten
adının smoosh
olarak yeniden adlandırılmasını önerdi. Espri herkes tarafından anlaşılmadı. Bazı kullanıcılar yeni adın zaten belirlenmiş olduğunu yanlış bir şekilde düşünmeye başladı ve işler hızla büyüdü.
Array.prototype.flatten
ne işe yarar?
Başlangıçta Array.prototype.flatten
olarak önerilen Array.prototype.flat
, dizileri belirtilen depth
değerine kadar (varsayılan olarak 1
) yinelemeli olarak düzleştirir.
// 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]
Aynı teklifte Array.prototype.flatMap
yer alır. Bu işlev, sonucu yeni bir dizi halinde düzleştirdiği dışında Array.prototype.map
ile aynıdır.
[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]
MooTools'un bu soruna neden olan işlemi nedir?
MooTools, Array.prototype.flatten
için standart olmayan kendi sürümünü tanımlar:
Array.prototype.flatten = /* non-standard implementation */;
MooAraçlar'ın flatten
uygulaması, önerilen standarttan farklı.
Ancak sorun bu değil. Tarayıcılar Array.prototype.flatten
'ü doğal olarak gönderdiğinde MooTools, doğal uygulamayı geçersiz kılar. Bu, yerel flatten
'ün kullanılabilir olup olmadığına bakılmaksızın MooTools davranışına dayalı kodun amaçlandığı gibi çalışmasını sağlar.
Şu ana kadar her şey yolunda.
Maalesef daha sonra başka bir şey olur. MooTools, tüm özel dizi yöntemlerini Elements.prototype
'e kopyalar (Elements
, MooTools'a özgü bir API'dir):
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
for
-in
, Array.prototype.sort
gibi yerel yöntemleri içermeyen ancak Array.prototype.foo = whatever
gibi düzenli olarak atanan özellikleri içeren "sayılabilir" özelliklerde iterasyon yapar. Ancak, sayılabilir olmayan bir mülkün (ör. Array.prototype.sort = whatever
) üzerine yazarsanız bu mülk sayılabilir olmayan olarak kalır.
Şu anda Array.prototype.flatten = mooToolsFlattenImplementation
, listelenebilir bir flatten
mülkü oluşturur. Bu nedenle, daha sonra Elements
'ye kopyalanır. Ancak tarayıcılar flatten
'ün yerel bir sürümünü gönderirse bu öğe sayılabilir olmaz ve Elements
'a kopyalanmaz. Mootools'un Elements.prototype.flatten
kullandığı kodlar artık çalışmaz.
Yerleşik Array.prototype.flatten
öğesinin sayılabilir olarak değiştirilmesi sorunu çözecek gibi görünse de bu işlem muhtemelen daha da fazla uyumluluk sorununa neden olur. Bir dizi üzerinde iterasyon yapmak için for
-in
kullanan her web sitesi (kötü bir uygulama olsa da bu durumla karşılaşılır) aniden flatten
mülkü için ek bir döngü iterasyonu alır.
Buradaki temel sorun, yerleşik nesnelerin değiştirilmesidir. Yerel prototipleri genişletmek, diğer kitaplıklar ve üçüncü taraf kodlarıyla iyi bir şekilde derlenmediği için günümüzde genellikle kötü bir uygulama olarak kabul edilir. Sahibi olmadığınız nesneleri değiştirmeyin.
Neden mevcut adı kullanmaya devam edip web'i bozmuyoruz?
1996'da, CSS yaygınlaşmadan ve "HTML5" henüz bir şeye dönüşmeden çok önce space Jam web sitesi yayındaydı. Bugün web sitesi, 22 yıl önce olduğu gibi çalışmaya devam ediyor.
Bu nasıl oldu? Bu web sitesini tüm bu yıllar boyunca koruyan ve tarayıcı tedarikçileri yeni bir özellik yayınladığında güncelleyen biri var mı?
Görünüşe göre "Web'i bozmayın", HTML, CSS, JavaScript ve Web'de yaygın olarak kullanılan diğer tüm standartlar için birincil tasarım ilkesi. Yeni bir tarayıcı özelliğinin kullanıma sunulması, mevcut web sitelerinin çalışmamasına neden olursa bu durum herkes için kötü olur:
- Etkilenen web sitelerinin ziyaretçileri aniden bozuk bir kullanıcı deneyimi yaşar;
- Web sitesi sahipleri, hiçbir şey değiştirmeden mükemmel çalışan bir web sitesine sahipken işlevsiz bir siteye sahip olduysa;
- yeni özelliği gönderen tarayıcı tedarikçileri, kullanıcıların "X tarayıcısında işe yaradığını" fark ettikten sonra tarayıcı değiştirmeleri nedeniyle pazar payını kaybeder;
- Uyumluluk sorunu bilindikten sonra diğer tarayıcı tedarikçileri bu sürümü göndermeyi reddeder. Özellik spesifikasyonu gerçekle eşleşmiyor ("yalnızca bir kurgu eseri"). Bu durum, standartlaştırma süreci için kötüdür.
Elbette, geriye dönük olarak MooTools yanlış bir şey yaptı. Ancak web'in kırılması onları cezalandırmaz, kullanıcıları cezalandırmaz. Bu kullanıcılar moo aracının ne olduğunu bilmiyor. Alternatif olarak başka bir çözüm bulabilir ve kullanıcıların web'i kullanmaya devam etmesini sağlayabiliriz. Bu tercihi yapmak kolaydır.
Does that mean bad APIs can never be removed from the Web Platform?
Duruma göre değişir. Nadir durumlarda, kötü özellikler web'den kaldırılabilir. Bir özelliğin kaldırılıp kaldırılamayacağını belirlemek bile çok zor bir işlemdir. Bu işlem, davranışı değişecek web sayfalarının sayısını ölçmek için kapsamlı telemetri gerektirir. Ancak özellik yeterince güvenli değilse, kullanıcılar için zararlıysa veya çok nadiren kullanılıyorsa bu işlem yapılabilir.
<applet>
, <keygen>
ve showModalDialog()
, Web Platformu'ndan başarıyla kaldırılan kötü API'lere örnek gösterilebilir.
Neden MooTools'u düzeltmiyoruz?
MooTools'u, artık yerleşik nesneleri genişletmeyecek şekilde düzeltmek iyi bir fikirdir. Yine de bu, mevcut sorunu çözmez. MooTools bir yama sürümü yayınlasa bile uyumluluk sorununun ortadan kalkması için bu sürümü kullanan tüm mevcut web sitelerinin güncellenmesi gerekir.
Kullanıcılar MooTools kopyalarını güncelleyemez mi?
İdeal bir dünyada MooTools bir yama yayınlar ve MooTools kullanan her web sitesi ertesi gün sihirli bir şekilde güncellenir. Sorun çözüldü, değil mi?
Maalesef bu mümkün değil. Bir şekilde etkilenen tüm web sitelerini tespit edip her birinin iletişim bilgilerini bulabilen, tüm web sitesi sahipleriyle iletişime geçebilen ve onları güncellemeyi yapmaya ikna edebilen (bu, tüm kod tabanlarının yeniden yapılandırılması anlamına gelebilir) bir kişi olsa bile tüm süreç en iyi ihtimalle yıllar sürer.
Bu web sitelerinin çoğunun eski ve muhtemelen bakımsız olduğunu unutmayın. Bakım uzmanı hâlâ aktif olsa bile sizin gibi yüksek vasıflı bir web geliştiricisi olmayabilir. Web uyumluluğu sorunu nedeniyle herkesin 8 yıllık web sitesini değiştirmesini bekleyemeyiz.
TC39 süreci nasıl işler?
TC39, ECMAScript standardı aracılığıyla JavaScript dilini geliştirmekten sorumlu komitedir.
#SmooshGate, bazı kullanıcıların "TC39'un flatten
adlı yeri smoosh
olarak değiştirmek istediği" düşüncesine neden oldu. Ancak bu, dışarıdan iyi iletişim kurmayan bir şakaydı.
Tekliflerin adını değiştirmek gibi önemli kararlar kolayca alınmaz, tek bir kişi tarafından verilmez ve kesinlikle tek bir GitHub yorumuna dayalı olarak bir gecede verilmez.
TC39, özellik önerileri için net bir aşamalandırma süreci uygular.
ECMAScript teklifleri ve bu tekliflerdeki önemli değişiklikler (yöntemi yeniden adlandırma dahil) TC39 toplantılarında tartışılır ve resmi hale gelmeden önce komitenin tamamı tarafından onaylanması gerekir. Array.prototype.flatten
durumunda, teklif 3. Aşama'ya kadar çeşitli anlaşma aşamalarından geçmiş durumda. Bu, özelliğin web tarayıcılarında uygulanmaya hazır olduğunu gösterir. Uygulama esnasında ek spesifikasyon
sorunları yaygın olarak görülür. Bu durumda, en önemli geri bildirim, özelliği kullanıma sunmaya çalıştıktan sonra geldi: Özellik, mevcut haliyle web'i bozuyor. Bunlar gibi tahmin edilmesi zor sorunlar, TC39 sürecinin yalnızca tarayıcılar bir özellik gönderdiğinde sona ermemesinin nedenlerinden biridir.
TC39, fikir birliğine dayalı olarak çalışır. Yani komitenin yeni değişiklikler üzerinde anlaşmaya varması gerekir. smoosh
ciddi bir öneride bulunmuş olsa da bir komite üyesi
compact
veya chain
gibi daha yaygın bir adın yerine buna itiraz edebilirdi.
flatten
olan adının smoosh
olarak değiştirilmesi (şaka olsa bile) hiçbir zaman TC39 toplantısında görüşülmedi. Bu nedenle, TC39'un bu konudaki resmi tutumu şu anda bilinmemektedir. Bir sonraki toplantıda fikir birliğine varılana kadar TC39'un tamamı adına tek bir kişi konuşamaz.
TC39 toplantılarına genellikle çok farklı geçmişlere sahip kişiler katılır: Bazılarının programlama dili tasarımı konusunda yıllarca tecrübesi vardır, bazıları ise tarayıcı veya JavaScript motoru üzerinde çalışır ve JavaScript geliştirici topluluğunu temsil etmek üzere her geçen gün daha fazla sayıda katılımcı bulunur.
SmooshGate sonuçta nasıl çözüldü?
Mayıs 2018'deki TC39 toplantısında #SmooshGate, flatten
adının
flat
olarak yeniden adlandırılmasıyla resmi olarak çözüme ulaştırıldı.
Array.prototype.flat
ve Array.prototype.flatMap
, V8 6.9 sürümünde ve Chrome 69'da kullanıma sunulmuştur.