คำถามที่พบบ่อยเกี่ยวกับ SmooshGate

เกิดอะไรขึ้นsmoosh

ข้อเสนอสำหรับ JavaScript ฟีเจอร์ภาษาชื่อ Array.prototype.flatten กลายเป็น ทำงานกับเว็บไม่ได้ การจัดส่งฟีเจอร์ใน Firefox Nightly ทำให้เว็บไซต์ยอดนิยมอย่างน้อย 1 เว็บไซต์ เพื่อทำลาย เนื่องจากโค้ดที่เป็นปัญหาเป็นส่วนหนึ่งของ MooTools ที่แพร่หลาย ก็มีแนวโน้มที่เว็บไซต์จำนวนมากขึ้นจะได้รับผลกระทบ (แม้ว่า MooTools ไม่นิยมใช้สำหรับเว็บไซต์ใหม่ๆ ในปี 2018 แต่เคยได้รับความนิยม ยังคงมีอยู่ในเว็บไซต์เวอร์ชันที่ใช้งานจริงอีกหลายแห่ง)

ผู้เขียนข้อเสนอเสนอแนะให้เปลี่ยนชื่อ flatten เป็น smoosh เป็น ให้หลีกเลี่ยงปัญหาเรื่องความเข้ากันได้ มุกตลกไม่ชัดเจนสำหรับทุกคน ผู้คนเริ่มมีความเชื่อผิดๆ ว่าชื่อใหม่นี้ได้ถูก และสิ่งต่างๆ ก็ส่งต่ออย่างรวดเร็ว

Array.prototype.flatten มีหน้าที่อะไร

Array.prototype.flat ซึ่งเดิมเสนอเป็น Array.prototype.flatten อาร์เรย์แบบ Flattens แบบวนซ้ำจนถึง 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 เป็นค่า API เฉพาะสำหรับ 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 เนทีฟเป็น enumerable จะช่วยแก้ปัญหา ซึ่งอาจทำให้ ปัญหาความเข้ากันได้ ทุกเว็บไซต์ที่ใช้ for-in ในการทำซ้ำ อาร์เรย์ (ซึ่งเป็นแนวทางปฏิบัติที่ไม่ดีแต่จริงๆ แล้วเกิดขึ้น) จากนั้นจู่ๆ ก็ได้รับ การทำซ้ำวนซ้ำเพิ่มเติมสำหรับพร็อพเพอร์ตี้ flatten

ปัญหาหลักที่สำคัญกว่าในที่นี้คือการแก้ไขออบเจ็กต์ในตัว กำลังขยายเวลา ปัจจุบันนี้ ต้นแบบที่สร้างขึ้นนั้นถือเป็นแนวทางปฏิบัติที่ไม่ดี เขียนได้ไม่ดีกับไลบรารีอื่นๆ และโค้ดของบุคคลที่สาม ห้ามแก้ไข สิ่งต่างๆ ที่คุณไม่ได้เป็นเจ้าของ

ทำไมเราไม่เก็บชื่อเดิมไว้และทำลายเว็บไปเลย

ในปี 1996 ก่อนที่ CSS จะแพร่หลาย และไม่นานก่อนที่ “HTML5” จะกลายเป็น เว็บไซต์ Space Jam ก็ได้เผยแพร่แล้ว ปัจจุบัน เว็บไซต์ยังคงใช้งานได้ เช่นเดียวกับเมื่อ 22 ปีที่แล้ว

เกิดขึ้นได้อย่างไร มีใครดูแลเว็บไซต์นั้นมาตลอดหลายปี มีการอัปเดตทุกครั้งที่ผู้ให้บริการเบราว์เซอร์จัดส่งฟีเจอร์ใหม่หรือไม่

ผลที่ได้คือ "อย่าทำลายเว็บ" เป็นหลักการออกแบบอันดับหนึ่ง สำหรับ HTML, CSS, JavaScript และมาตรฐานอื่นๆ ที่ใช้กันอย่างแพร่หลายใน เว็บ หากการจัดส่งฟีเจอร์เบราว์เซอร์ใหม่ทำให้เว็บไซต์ที่มีอยู่หยุดทำงาน ที่ทำงานไม่ดีต่อทุกคน

  • ผู้เข้าชมเว็บไซต์ที่ได้รับผลกระทบได้รับประสบการณ์การใช้งานที่ไม่ดีกะทันหัน
  • เจ้าของเว็บไซต์ก็เปลี่ยนจากการมีเว็บไซต์ที่ทำงานได้สมบูรณ์แบบ ไม่ทำงานโดยไม่มีการเปลี่ยนแปลงอะไรเลย
  • ผู้ให้บริการเบราว์เซอร์ที่ส่งฟีเจอร์ใหม่เสียส่วนแบ่งการตลาดเนื่องจากผู้ใช้ เปลี่ยนเบราว์เซอร์หลังจากสังเกตเห็นว่า "ใช้งานได้ในเบราว์เซอร์ X"
  • เมื่อทราบปัญหาด้านความเข้ากันได้แล้ว ผู้ให้บริการเบราว์เซอร์รายอื่นก็ปฏิเสธที่จะ ได้ ข้อมูลจำเพาะของฟีเจอร์ไม่ตรงกับความเป็นจริง ("ไม่มีอะไรเลยนอกจากผลงานนิยาย") ซึ่งจะส่งผลเสียต่อกระบวนการกำหนดมาตรฐาน

แน่นอนว่า MooTools ทำผิดไปแล้ว แต่กลับทำให้เว็บพังได้ พวกเขาไม่มีบทลงโทษ แต่ลงโทษผู้ใช้แล้ว ผู้ใช้เหล่านี้ไม่รู้ว่า "โมทย์" คืออะไร เครื่องมืออย่างหนึ่ง อีกวิธีหนึ่งคือ เราสามารถหาโซลูชันอื่น และผู้ใช้ ในการใช้เว็บ ทางเลือกนี้สามารถทำได้ง่าย

นั่นหมายความว่าจะไม่มีการนำ API ที่ไม่ดีออกจากแพลตฟอร์มเว็บเลยใช่ไหม

แล้วแต่กรณี ในบางกรณีที่พบไม่บ่อย ฟีเจอร์ที่ไม่ดีอาจถูกนำออกจากเว็บ แม้แค่คิดว่า ว่าเป็นไปได้ที่จะนำฟีเจอร์ใดออก เป็นความพยายามที่ยุ่งยากมาก ซึ่งต้องอาศัยการวัดและส่งข้อมูลทางไกลอย่างครอบคลุมเพื่อวัดจำนวนหน้าเว็บที่มี เปลี่ยนพฤติกรรมแล้ว แต่เมื่อฟีเจอร์นี้ไม่ปลอดภัยพอ จะเป็นอันตรายต่อ หรือมีการใช้งานน้อยมาก ก็สามารถทำได้

<applet>, <keygen> และ showModalDialog() ทั้งหมด ตัวอย่างของ API ที่ไม่ถูกต้อง ซึ่งนำออกจากแพลตฟอร์มเว็บเรียบร้อยแล้ว

ทำไมเราไม่แก้ไข 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 v6.9 และ Chrome 69