¿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.