ماذا حدث للحظة؟
اقتراح لـ 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):
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
يتكرر for
-in
على سمات "enumerable"، والتي لا تتضمن
طرق أصلية مثل Array.prototype.sort
، لكنها تشمل
السمات المعينة بانتظام مثل Array.prototype.foo = whatever
. ولكن —
وفي ما يلي العنوان الجانبي: إذا استبدلت خاصية غير قابلة للتعداد، على سبيل المثال:
Array.prototype.sort = whatever
، يظل غير قابل للتعداد.
حاليًا، تنشئ قناة "Array.prototype.flatten = mooToolsFlattenImplementation
"
سمة flatten
قابلة للعدد، لذلك يتم نسخها لاحقًا إلى Elements
ولكن إذا
تشحن المتصفحات إصدارًا أصليًا من flatten
، ويصبح غير قابل للتعداد،
لا يتم نسخه إلى Elements
. أي رمز برمجي يعتمد على MooTools
جهاز Elements.prototype.flatten
معطَّل الآن.
على الرغم من أنّه يبدو أنّه سيتم تغيير بيانات Array.prototype.flatten
الأصلية لتصبح
يمكن تعداده أن يحل المشكلة، ومن المحتمل أن يتسبب في المزيد
مشكلات التوافق. يعتمد كل موقع إلكتروني على for
-in
لتكرار المحتوى
لنفترض أن هناك صفيفًا (وهو ممارسة سيئة، ولكنه يحدث) ستظهر فجأة
تكرارًا تكراريًا إضافيًا للسمة flatten
.
والمشكلة الأساسية الأكبر هنا هي تعديل الكائنات المضمنة. توسيع والنماذج الأولية الأصلية بشكل عام كممارسة سيئة في الوقت الحاضر، حيث إنها لا ينشئ بشكل جيد مع المكتبات الأخرى والتعليمات البرمجية التابعة لجهات خارجية. عدم التعديل عناصر لا تملكها!
فلماذا لا نحتفظ بالاسم الموجود ونقطع الويب فقط؟
في عام 1996، قبل انتشار CSS، وقبل انتشار "HTML5" لفترة طويلة أنه تم إطلاق موقع Space Jam الإلكتروني. اليوم، لا يزال الموقع الإلكتروني يعمل بالطريقة نفسها التي كانت عليه منذ 22 عامًا.
كيف حدث ذلك؟ هل قام شخص ما بصيانة هذا الموقع طوال هذه السنوات، أو تحديثه في كل مرة يشحن مورّدو المتصفحات ميزة جديدة؟
لقد اتضح أنّ "عدم تقسيم الويب" هو مبدأ التصميم الأساسي. HTML وCSS وJavaScript وأي معيار آخر يُستخدم على نطاق واسع في الويب في حال تسبّب شحن ميزة متصفّح جديدة في إيقاف المواقع الإلكترونية الحالية في حال نجحت، وهو أمر سيئ للجميع:
- فجأة يحصل زوّار المواقع الإلكترونية المتأثرة على تجربة مستخدم معطّلة
- فإن مالكي مواقع الويب انتقلوا من امتلاك موقع ويب يعمل بشكل مثالي إلى واحدة غير وظيفية دون أن تغير أي شيء؛
- بائعو المتصفحات الذين يشحنون الميزة الجديدة يفقدون حصتهم في السوق، بسبب المستخدمين التبديل بين المتصفحات بعد ملاحظة "يعمل في المتصفّح X"
- عند معرفة مشكلة التوافق، يرفض موردو المتصفحات الآخرون شحن بها. عدم تطابق مواصفات الميزة مع الواقع ("ليس هناك سوى عمل خيالي) وهو أمر سيئ لعملية توحيد المقاييس.
بالتأكيد، من الناحية الاسترجاعية، لم تتّخذ Mootools إجراءً ذا صلة، ولكن أدّى ذلك إلى كسر الإنترنت. لا يعاقب عليه، بل يعاقب المستخدمين. هؤلاء المستخدمون لا يعرفون ما الذي الأداة. بدلاً من ذلك، يمكننا إيجاد حل آخر، ويمكن للمستخدمين المتابعة لاستخدام الويب. هذا الاختيار سهل.
هل يعني ذلك أنّه لا يمكن إزالة واجهات برمجة التطبيقات غير الصالحة من منصة الويب؟
يعتمد ذلك على بعض العوامل. في حالات نادرة، يمكن إزالة ميزات سيئة من الويب. حتى مجرد معرفة فإن معرفة ما إذا كان من الممكن إزالة ميزة هو إجراء معقد للغاية، مما يتطلب قياسًا مكثفًا عن بُعد لتحديد عدد صفحات الويب معين. ولكن عندما تكون الميزة غير آمنة بما فيه الكفاية، يكون ضارًا المستخدمين، أو عندما يتم استخدامه نادرًا، فيمكن تنفيذ ذلك.
<applet>
و<keygen>
و
showModalDialog()
جميعها
أمثلة لواجهات برمجة تطبيقات غير صالحة تمت إزالتها بنجاح من نظام الويب الأساسي.
لمَ لا نكتفي بإصلاح MooTools؟
من الأفضل تصحيح أخطاء MooTools بحيث لا توسّع نطاق الكائنات المدمجة الفكرة. ومع ذلك، فإنه لا يحل المشكلة المطروحة. حتى لو تم استخدام MooTools لإصدار نسخة مصححة، سيتعين على جميع المواقع الإلكترونية الحالية التي تستخدمها تحديث لحل مشكلة التوافق.
ألا يمكن للأشخاص تحديث نسختهم من MooTools فقط؟
في عالم مثالي، يطلق MooTools رمز تصحيح، ويبدأ كل موقع ويب استخدام MooTools بشكل سحري في اليوم التالي. تم حل المشكلة، أليس كذلك؟!
للأسف، هذا غير واقعي. حتى لو تم تحديد هوية شخص ما بطريقة ما المجموعة الكاملة لمواقع الويب المتأثرة، يمكنك العثور على معلومات الاتصال التواصل بنجاح مع جميع مالكي المواقع الإلكترونية وإقناعهم جميعًا بإجراء التحديث (مما قد يعني إعادة الهيكلة قاعدة التعليمات البرمجية بأكملها)، فإن العملية بأكملها ستستغرق سنوات، في أحسن الأحوال.
يُرجى العِلم أنّ العديد من هذه المواقع الإلكترونية قديمة ومن المحتمل أنّه لم يتم الحفاظ عليها. حتى إذا كان المشرف لا يزال موجودًا، فمن المحتمل أنه ليس مطور ويب ذو مهارات عالية مثلك. لا نتوقع أن يذهب الجميع وتغيير موقعها الإلكتروني الذي يبلغ من العمر 8 أعوام بسبب مشكلة في التوافق مع الويب.
ما هي آلية عمل إطار الشفافية والموافقة TC39؟
TC39 هي اللجنة المسؤولة عن تطوير لغة JavaScript من خلال بمعيار ECMAScript.
تسببت عبارة #SmooshGate في اعتقاد البعض أنّ "TC39 يريد إعادة تسمية 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
إلى الإصدار V8 من الإصدار 6.9،
الإصدار 69 من Chrome: