Preguntas frecuentes sobre SmooshGate

¿Qué smoosh ocurrió?

Una propuesta para JavaScript de idioma llamada Array.prototype.flatten resulta ser No es compatible con la Web. El envío de la función en Firefox Nightly generó al menos un sitio web popular romperse. Dado que el código problemático es parte de las herramientas generalizadas de MooTools biblioteca, es probable que se vean afectados muchos más sitios web. (Aunque MooTools no se usa comúnmente para sitios web nuevos en 2018, solía ser muy popular y sigue presente en muchos sitios web de producción).

En broma, el autor de la propuesta sugirió cambiar el nombre de flatten a smoosh por evitar el problema de compatibilidad. La broma no era clara para todos, algunos empezaron a creer erróneamente que el nuevo nombre ya había sido y las cosas aumentaron rápidamente.

¿Qué hace Array.prototype.flatten?

Array.prototype.flat, que originalmente se propuso como Array.prototype.flatten, aplana los arrays de forma recursiva hasta el depth especificado, que es el valor predeterminado. a 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]

La misma propuesta incluye Array.prototype.flatMap, que es lo siguiente: Array.prototype.map, excepto que compacta el resultado en un array nuevo.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

¿Qué está haciendo MooTools que causa este problema?

MooTools define su propia versión no estándar de Array.prototype.flatten:

Array.prototype.flatten = /* non-standard implementation */;

La implementación de flatten de MooTools difiere del estándar propuesto. Sin embargo, este no es el problema. Cuando se envían los navegadores Array.prototype.flatten de forma nativa, MooTools anula la versión nativa. para implementarlos. Esto garantiza que el código dependa del comportamiento de MooTools Funciona según lo previsto, independientemente de si flatten nativo está disponible. Todo bien por ahora.

Lamentablemente, sucede algo más. MooTools copia todo su métodos de array personalizados a Elements.prototype (donde Elements es un API específica de MooTools):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-in itera en propiedades "enumerables", que no incluyen métodos nativos como Array.prototype.sort, pero incluye propiedades asignadas con regularidad, como Array.prototype.foo = whatever. Pero... y esta es la sugerencia: si reemplazas una propiedad no enumerable, p.ej., Array.prototype.sort = whatever, sigue siendo no enumerable.

Actualmente, Array.prototype.flatten = mooToolsFlattenImplementation crea Una propiedad flatten enumerable, por lo que luego se copia en Elements. Pero si los navegadores envían una versión nativa de flatten, que no es enumerable y no se copia en Elements. Cualquier código que dependa de la tecnología de Elements.prototype.flatten ya no funciona.

Aunque parezca que cambiar el Array.prototype.flatten nativo para que sea enumerable solucionaría el problema, probablemente causaría aún más problemas de compatibilidad. Todos los sitios web que dependen de for-in para iterar un array (lo cual no es una práctica recomendada, pero sucede) se convierte de repente una iteración de bucle adicional para la propiedad flatten

El mayor problema subyacente aquí es la modificación de objetos integrados. Extendiendo de prototipos nativos se acepta generalmente como una mala práctica, ya que no funciona bien con otras bibliotecas y código de terceros. No modificar que no te pertenecen.

¿Por qué no se conserva el nombre actual y se abre la Web?

En 1996, antes de que CSS se expandiera y mucho antes de que “HTML5” se volviera un el sitio web de Space Jam se lanzó. Hoy en día, el sitio web sigue funcionando del mismo modo que lo hizo hace 22 años.

¿Cómo sucedió eso? ¿Alguien mantuvo ese sitio web durante todos estos años? cada vez que los proveedores de navegadores lanzaban una función nueva?

Como se puede ver, "no rompas la Web" es el principio de diseño número uno. para HTML, CSS, JavaScript y cualquier otro estándar usado ampliamente en Web. Si el envío de una nueva función del navegador provoca que se detengan los sitios web existentes funciona, eso es malo para todos:

  • los visitantes de los sitios web afectados experimentan de repente una experiencia del usuario negativa;
  • los propietarios de los sitios web pasaron de tener un sitio web perfectamente funcional a uno no funcional sin que ellos cambien nada;
  • los proveedores de navegadores que envían la nueva función pierden participación de mercado debido a que los usuarios cambiar de navegador después de notar que "funciona en el navegador X";
  • una vez que se conoce el problema de compatibilidad, otros proveedores de navegadores se niegan a enviar que la modifica. La especificación de la función no coincide con la realidad (“solo una obra de ficción”). lo que es malo para el proceso de estandarización.

Claro, en retrospectiva, MooTools hizo lo incorrecto, pero romper la Web no los castiga a los usuarios. Estos usuarios no saben qué moo. de tu herramienta. Como alternativa, podemos encontrar otra solución, y los usuarios pueden continuar para usar la Web. La decisión es fácil de hacer.

¿Significa que nunca se podrán quitar las APIs dañinas de la plataforma web?

Depende. En casos excepcionales, es posible que se quiten las funciones no seguras de la Web. Incluso el solo hecho de calcular si es posible quitar un atributo es un esfuerzo muy complejo que requieren una telemetría extensa para cuantificar cuántas páginas web tendrían cambió el comportamiento. Pero, cuando la función es lo suficientemente insegura, es perjudicial para usuarios, o si se usa muy pocas veces, es posible.

<applet>, <keygen> y showModalDialog() son todas ejemplos de APIs maliciosas que se quitaron con éxito de la plataforma web.

¿Por qué no solo arreglamos MooTools?

Aplicar parches a MooTools para que ya no extienda los objetos integrados es una buena idea. Sin embargo, no resuelve el problema en cuestión. Incluso si MooTools fuera para lanzar una versión de parche, todos los sitios web existentes que la usaran tendrían que para que el problema de compatibilidad desaparezca.

¿Las personas no pueden simplemente actualizar su copia de MooTools?

En un mundo ideal, MooTools lanzaría un parche y cada sitio web con MooTools se actualizaría al día siguiente. Problema resuelto, ¿verdad?

Lamentablemente, esto no es realista. Incluso si alguien se identificara todo el conjunto de sitios web afectados, encontrar la información de contacto de todos y cada uno de ellos comunicarse exitosamente con todos los propietarios de sitios web, y convencerlos a todos para que realicen la actualización (lo que podría significar refactorizar toda su base de código), el proceso completo tardaría años, en el mejor de los casos.

Recuerda que muchos de estos sitios web son antiguos y probablemente no tengan mantenimiento. Incluso si el encargado del mantenimiento sigue estando disponible, es posible que no sea un desarrollador web altamente calificado como tú. No podemos esperar que todos vayan y cambiar el sitio web de hace 8 años debido a un problema de compatibilidad web.

¿Cómo funciona el proceso TC39?

TC39 es el comité a cargo de hacer evolucionar el lenguaje JavaScript mediante el estándar ECMAScript.

#SmooshGate hizo que algunas personas creyeran que “TC39 quiere cambiar el nombre de flatten a smoosh”, pero era un chiste interno que no se comunicaba bien externamente. Las decisiones importantes, como cambiar el nombre de una propuesta, no se toman a la ligera una sola persona y, definitivamente, no se toman de la noche a la mañana según una única comentario de GitHub.

TC39 opera en un proceso claro de etapa de pruebas para las propuestas de atributos. Propuestas de ECMAScript y cualquier cambio importante en ellas (incluido el método cambio de nombre) se analizan en las reuniones de la TC39 y deben contar con la aprobación del todo el comité antes de que sean oficiales. En el caso de Array.prototype.flatten, la propuesta ya pasó por varias del acuerdo hasta la etapa 3, que indica que la función está lista para implementarse en navegadores web. Es común incluir especificaciones adicionales problemas que surjan durante la implementación. En este caso, lo más importante comentarios surgieron después de intentar enviarlo: la función, en su estado actual, rompe la Web. Los problemas difíciles de predecir como estos son parte de la razón por la el proceso TC39 no termina cuando los navegadores envían una función.

TC39 opera según el consenso, lo que significa que el comité debe acordar cualquier nueva cambios. Incluso si smoosh hubiera sido una sugerencia seria, parece probable que un miembro del comité se opone a ello y preferiría un nombre más común, como compact o chain.

El cambio de nombre de flatten a smoosh (incluso si no fue una broma) que nunca se discutieron en una reunión de TC39. Por lo tanto, la postura oficial ante el TC39 sobre este tema es desconocido actualmente. Ninguna persona puede hablar en nombre de los TC39 hasta que se llegue a un consenso en la próxima reunión.

Por lo general, asisten a las reuniones TC39 de personas con otros tienen años de experiencia en el diseño de lenguajes de programación, otros trabajan en un navegador o motor de JavaScript, y una cantidad cada vez mayor de los asistentes están para representar a la comunidad de desarrolladores de JavaScript.

¿Cómo se resolvió SmooshGate finalmente?

Durante la reunión de TC39 de mayo de 2018, #SmooshGate se resolvió oficialmente cambiando el nombre de flatten a flat.

Array.prototype.flat y Array.prototype.flatMap se enviaron en la versión 8 v6.9 y Chrome 69.