ماذا حدث؟
تبيّن أنّ اقتراحًا لميزات لغة JavaScript
المعروفة باسم Array.prototype.flatten
ليس
متوافقًا مع الويب. أدّى طرح الميزة في Firefox Nightly إلى تعطُّل موقع إلكتروني شهير واحد على الأقل. بما أنّ الرمز البرمجي الذي يتضمّن المشكلة هو جزء من مكتبة MooTools
الواسعة الانتشار، من المرجّح أن يتأثّر عدد أكبر من المواقع الإلكترونية. (على الرغم من أنّ MooTools
لا يتم استخدامه بشكل شائع للمواقع الإلكترونية الجديدة في عام 2018، إلا أنّه كان رائجًا جدًا ويُستخدم
حتى الآن في العديد من المواقع الإلكترونية المخصّصة للنشر).
اقترح كاتب الاقتراح بشكل مازح إعادة تسمية flatten
إلى smoosh
لتجنُّب مشكلة التوافق. لم تكن هذه المزحة واضحة للجميع، فبدأ بعض
المستخدمين يعتقدون بشكل خاطئ أنّه سبق أن تم تحديد
الاسم الجديد، وتصاعدت الأمور بسرعة.
ما هي وظيفة Array.prototype.flatten
؟
دالة Array.prototype.flat
، التي تم اقتراح استخدامها في الأصل باسم Array.prototype.flatten
،
تسطّح الصفائف بشكل تسلسلي إلى أن تصل إلى depth
المحدّد، والذي يتم ضبطه تلقائيًا
على 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]
يتضمّن الاقتراح نفسه Array.prototype.flatMap
، وهو مشابه لمحاولة
Array.prototype.map
باستثناء أنّه يُسطّح النتيجة في صفيف جديد.
[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]
ما هي الإجراءات التي يتّخذها MooTools والتي تؤدي إلى حدوث هذه المشكلة؟
تحدِّد MooTools نسخة غير عادية من Array.prototype.flatten
:
Array.prototype.flatten = /* non-standard implementation */;
يختلف تنفيذ flatten
في MooTools عن المعيار المقترَح.
ولكن هذه ليست المشكلة. عندما تُرسِل المتصفّحات
Array.prototype.flatten
بشكلٍ أصلي، تلغي MooTools التنفيذ
الأصلي. يضمن ذلك أنّ الرمز البرمجي الذي يعتمد على سلوك MooTools يعمل كما هو مطلوب بغض النظر عمّا إذا كان flatten
الأصلي متاحًا.
كل الأمور جيدة حتى الآن
ولكن يحدث بعد ذلك أمر آخر. تنسخ MooTools كل Elements.prototype
(حيث Elements
هي واجهة برمجة تطبيقات خاصة بموفّر MooTools) من Elements.prototype
:
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
for
-in
يكرّر السمات "القابلة للعدّ"، والتي لا تتضمّن methods برمجية أصلية مثل Array.prototype.sort
، ولكنها تتضمّن سمات تم تعيينها بشكل منتظم مثل Array.prototype.foo = whatever
. ولكن،
في ما يلي النقطة المهمة: في حال استبدال خاصيّة غير قابلة للتعداد، مثل
Array.prototype.sort = whatever
، ستظلّ غير قابلة للتعداد.
في الوقت الحالي، ينشئ Array.prototype.flatten = mooToolsFlattenImplementation
خاصية flatten
قابلة للعدّ، لذلك يتم نسخها لاحقًا إلى Elements
. ولكن إذا كانت
المتصفحات توفّر إصدارًا أصليًا من flatten
، يصبح غير قابل للعدّ، ولا يتم نسخه إلى Elements
. إنّ أي رمز يعتمد على Elements.prototype.flatten
في MooTools أصبح الآن متعطّلاً.
على الرغم من أنّه يبدو أنّ تغيير Array.prototype.flatten
الأصلي ليصبح
قابلاً للعدّ قد يؤدي إلى حلّ المشكلة، إلا أنّه من المحتمل أن يؤدي إلى حدوث المزيد من
مشاكل التوافق. سيحصل كل موقع إلكتروني يعتمد على for
-in
للتكرار على
صفيف (وهي ممارسة سيئة، ولكنّها تحدث) على
تكرار حلقة إضافي للسمة flatten
.
إنّ المشكلة الأساسية الأكبر هنا هي تعديل العناصر المضمّنة. يُعدّ استخدام نماذج أولية برمجية أساسية لتمديد الوظائف من الممارسات السيئة بشكل عام في الوقت الحالي، لأنّه لا يتوافق بشكل جيد مع المكتبات الأخرى والرموز البرمجية التابعة لجهات خارجية. لا تعدِّل العناصر التي لا تملكها.
لماذا لا نحتفظ بالاسم الحالي ونُوقف الويب؟
في عام 1996، قبل أن تنتشر لغة CSS على نطاق واسع، وقبل أن تصبح لغة HTML5 متوفّرة، تم نشر موقع Space Jam الإلكتروني. لا يزال الموقع الإلكتروني يعمل بالطريقة نفسها التي كان يعمل بها قبل 22 عامًا.
كيف حدث ذلك؟ هل كان هناك شخص يحافظ على هذا الموقع الإلكتروني طوال هذه السنوات، ويُجري تعديلات عليه في كل مرة يطرح فيها مورّدو المتصفّحات ميزة جديدة؟
تبيّن أنّ "عدم تعطيل الويب" هو مبدأ التصميم الأول للغات HTML وCSS وJavaScript وأي معيار آخر يستخدم على نطاق واسع على الويب. إذا أدّى طرح ميزة جديدة في المتصفّح إلى إيقاف عمل المواقع الإلكترونية الحالية، سيكون ذلك أمرًا سيئًا للجميع:
- يواجه زوّار المواقع الإلكترونية المتأثرة فجأةً تجربة استخدام متعطّلة.
- مالك الموقع الإلكتروني كان يمتلك موقعًا إلكترونيًا يعمل بشكلٍ مثالي، ولكن أصبح الموقع الإلكتروني غير فعّال بدون أن يُجري أي تغييرات
- يفقد مورّدو المتصفّحات الذين يطرحون الميزة الجديدة حصّة السوق، لأنّ المستخدمين يبدّلون المتصفّحات بعد ملاحظة أنّ "الميزة تعمل في المتصفّح X".
- بعد معرفة مشكلة التوافق، يرفض مورّدو المتصفحات الآخرون إرسال التطبيق. لا تتطابق مواصفات الميزة مع الواقع ("ما هي إلا عمل خيالي")، وهو أمر سلبي لعملية وضع المعايير.
بالتأكيد، بعد النظر في الأمر، اتّخذت MooTools الإجراء الخاطئ، ولكنّ تعطيل الويب لا يعاقب هذه الشركة، بل يعاقب المستخدمين. لا يعرف هؤلاء المستخدمون ما هي أداة moo. بدلاً من ذلك، يمكننا العثور على حلّ آخر، ويمكن للمستخدمين مواصلة استخدام الويب. يمكنك بسهولة تحديد ما إذا كنت تريد استخدام هذه الميزة أم لا.
هل يعني ذلك أنّه لا يمكن أبدًا إزالة واجهات برمجة التطبيقات السيئة من Web Platform؟
يعتمد ذلك على بعض العوامل. في حالات نادرة، يمكن إزالة الميزات الضارّة من الويب. إنّ معرفة ما إذا كان من الممكن إزالة ميزة ما هو أمر صعب للغاية، ويتطلب جمع بيانات قياسية مكثفة لتحديد عدد صفحات الويب التي قد يتغيّر سلوكها. ولكن يمكن إجراء ذلك عندما تكون الميزة غير آمنة بما يكفي أو ضارة بالمستخدمين أو نادرًا ما يتم استخدامها.
<applet>
و<keygen>
و
showModalDialog()
هي
أمثلة على واجهات برمجة التطبيقات غير الصالحة التي تمّت إزالتها بنجاح من النظام الأساسي للويب.
لماذا لا نصلح MooTools فقط؟
من الجيد تعديل MooTools كي لا تمتدّ إلى الكائنات المضمّنة. ومع ذلك، لا يحلّ هذا الإجراء المشكلة الحالية. حتى إذا تم إصدار إصدار معدَّل من MooTools، يجب أن يتم تحديث جميع المواقع الإلكترونية الحالية التي تستخدمه لإزالة مشكلة التوافق.
ألا يمكن للمستخدمين تحديث نسختهم من MooTools؟
في عالم مثالي، ستُصدر MooTools تصحيحًا، وسيتمّ تحديث كلّ موقع إلكتروني يستخدِم MooTools بطريقة سحرية في اليوم التالي. تم حلّ المشكلة، أليس كذلك؟
للأسف، هذا غير واقعي. حتى إذا تمكّن أحد الأشخاص من تحديد المجموعة الكاملة من المواقع الإلكترونية المتأثرة، وتمكن من العثور على معلومات الاتصال بكل موقع إلكتروني منها، والتواصل بنجاح مع جميع مالكي المواقع الإلكترونية، وإقناعهم جميعًا بإجراء التعديل (ما قد يعني إعادة تنظيم قاعدة الرموز البرمجية بالكامل)، ستستغرق العملية بأكملها سنوات في أحسن الأحوال.
يُرجى العِلم أنّ العديد من هذه المواقع الإلكترونية قديمة ومن المحتمل أنّها لم يتم الاحتفاظ بها. حتى إذا كان المشرف لا يزال متاحًا، من المحتمل أنّه ليس مطوّر ويب ماهرًا مثلك. لا يمكننا أن نتوقع من الجميع تغيير موقعهم الإلكتروني الذي تم إنشاؤه قبل 8 سنوات بسبب مشكلة في التوافق مع الويب.
كيف تتم عملية TC39؟
لجنة TC39 هي اللجنة المسؤولة عن تطوير لغة JavaScript من خلال معيار ECMAScript.
أدّى الهاشتاغ #SmooshGate إلى اعتقاد البعض أنّ "اللجنة التقنية 39 تريد إعادة تسمية flatten
إلى
smoosh
"، ولكنّه كان مزحة داخلية لم يتم توضيحها جيدًا للجهات الخارجية.
لا يتم اتخاذ القرارات الرئيسية، مثل إعادة تسمية اقتراح، بشكل عفوي، ولا يتم اتخاذها
بواسطة شخص واحد، ولا يتم اتخاذها بالتأكيد بين عشية وضحاها استنادًا إلى مناقشة واحدة في GitHub.
تعتمد مجموعة TC39 عملية إعداد واضحة لاقتراحات الميزات.
تتم مناقشة اقتراحات ECMAScript وأي تغييرات كبيرة عليها (بما في ذلك إعادة تسمية الأسلوب) خلال اجتماعات TC39، ويجب أن توافق عليها الكوميسيون بأكملها قبل أن تصبح رسمية. في ما يتعلّق بميزة
Array.prototype.flatten
، سبق أن مرّ الاقتراح بعدة
مراحل من الاتفاق، وصولاً إلى المرحلة 3، ما يشير إلى أنّ الميزة
جاهزة للتنفيذ في متصفّحات الويب. من الشائع أن تظهر أثناء التنفيذ
مشاكل إضافية في المواصفات. في هذه الحالة، جاءت أهم ملاحظات العميل بشأن الميزة بعد محاولة طرحها: إنّ الميزة في حالتها الحالية تؤدي إلى تعطُّل الويب. إنّ المشاكل التي يصعب توقّعها، مثل هذه المشاكل، هي جزء من الأسباب التي تجعل
عملية TC39 لا تنتهي بعد طرح المتصفّحات لميزة معيّنة.
تعمل مجموعة TC39 على أساس الإجماع، ما يعني أنّ على اللجنة الموافقة على أي
تغييرات جديدة. حتى لو كان "smoosh
" اقتراحًا جديًا، من المرجّح أن يرفضه أحد أعضاء اللجنة لصالح اسم أكثر شيوعًا مثل "compact
" أو "chain
".
لم تتم مناقشة عملية إعادة التسمية من flatten
إلى smoosh
(حتى لو لم تكن مزحة)
في أي اجتماع من اجتماعات TC39. وبالتالي، فإنّ الموقف الرسمي للجنة TC39 بشأن
هذا الموضوع غير معروف حاليًا. لا يمكن لأي شخص واحد التحدث نيابةً عن
جميع أعضاء TC39 إلى أن يتمّ التوصل إلى توافق في الرأي في الاجتماع التالي.
ينضم إلى اجتماعات TC39 بشكل عام أشخاص لديهم خلفيات متنوعة للغاية: يمتلك البعض منهم سنوات من الخبرة في تصميم لغات البرمجة، ويشارك آخرون في تطوير متصفّح أو محرّك JavaScript، ويشارك عدد متزايد من الحضور لتمثيل منتدى مطوّري JavaScript.
كيف تم حلّ SmooshGate في النهاية؟
خلال اجتماع TC39 في أيار (مايو) 2018، تم حلّ مشكلة #SmooshGate
رسميًا من خلال إعادة تسمية flatten
إلى flat
.
تم طرح Array.prototype.flat
وArray.prototype.flatMap
في الإصدار 6.9 من V8 و Chrome 69.