O que o smoosh aconteceu?!
Uma proposta para um JavaScript
um recurso de idioma chamado Array.prototype.flatten
é
Incompatível com a Web. O envio do recurso no Firefox Nightly fez com que pelo menos um site popular
quebrar. Como o código problemático faz parte da interface comum do MooTools
é provável que muitos outros sites sejam afetados. (Embora o MooTools
não é comumente usado para novos sites em 2018, era muito popular e
ainda está presente em muitos sites de produção.)
O autor da proposta, brincando, sugeriu renomear flatten
como smoosh
para
evitar o problema de compatibilidade. A piada não foi clara para todos, alguns
as pessoas começaram a acreditar incorretamente que o novo nome já havia sido
decidido, e as coisas se escalaram rapidamente.
O que o Array.prototype.flatten
faz?
Array.prototype.flat
, proposta originalmente como Array.prototype.flatten
,
nivela matrizes recursivamente até o depth
especificado, que assume o padrão
para 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]
A mesma proposta inclui Array.prototype.flatMap
, que é semelhante a
Array.prototype.map
, exceto por nivelar o resultado em uma nova matriz.
[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]
O que o MooTools está fazendo para causar esse problema?
O MooTools define a própria versão não padrão de Array.prototype.flatten
:
Array.prototype.flatten = /* non-standard implementation */;
A implementação do flatten
no MooTools é diferente do padrão proposto.
No entanto, esse não é o problema. Quando os navegadores são enviados
Array.prototype.flatten
nativamente, o MooTools substitui o nativo
implementação. Isso garante que o código que depende do comportamento do MooTools
funciona conforme o esperado, independentemente de a flatten
nativa estar disponível.
Até aqui, tudo bem!
Infelizmente, acontece outra coisa. O MooTools copia todas as
métodos de matriz personalizados para Elements.prototype
(em que Elements
é um
API específica do MooTools):
for (var key in Array.prototype) {
Elements.prototype[key] = Array.prototype[key];
}
for
-in
itera em propriedades "enumeráveis", que não incluem
métodos nativos, como Array.prototype.sort
, mas inclui
propriedades atribuídas regularmente, como Array.prototype.foo = whatever
. Mas...
e este é o chapéu, se você substituir uma propriedade não enumerável, por exemplo,
Array.prototype.sort = whatever
, permanece não enumerável.
No momento, o Array.prototype.flatten = mooToolsFlattenImplementation
cria
uma propriedade flatten
enumerável, que vai ser copiada para Elements
depois. Mas se
navegadores enviam uma versão nativa de flatten
, ela se torna não enumerável e
não é copiado para Elements
. Qualquer código que dependa do MooTools
O Elements.prototype.flatten
agora está corrompido.
Embora isso pareça mudar o Array.prototype.flatten
nativo para ser
enumerável corrigiria o problema, provavelmente causaria ainda mais
problemas de compatibilidade. Todos os sites que dependem de for
a in
para fazer iterações
uma matriz (o que é uma prática não recomendada, mas acontece) de repente ficaria
uma iteração de loop adicional para a propriedade flatten
.
O maior problema subjacente aqui é modificar objetos integrados. Estendendo de protótipos nativos geralmente é aceito como uma má prática hoje em dia, não funciona bem com outras bibliotecas e códigos de terceiros. Não modificar objetos que não são seus.
Por que simplesmente não mantemos o nome atual e quebramos a Web?
Em 1996, antes do CSS se disseminar, e muito antes do "HTML5" o site da Space Jam foi lançado. Hoje, o site ainda funciona da mesma forma que 22 anos atrás.
Como isso aconteceu? Alguém manteve esse site por todos esses anos, atualizando sempre que os fornecedores de navegador lançam um novo recurso?
Na verdade, "não quebrar a Web" é o princípio de design número um. para HTML, CSS, JavaScript e qualquer outro padrão amplamente utilizado na Web. Se o envio de um novo recurso do navegador fizer com que os sites atuais parem de funcionar funcionando, é ruim para todos:
- os visitantes dos sites afetados tiveram uma experiência do usuário corrompida;
- os proprietários de sites deixaram de ter um site perfeitamente funcional para um não funcional sem que ela altere nada;
- os fornecedores de navegadores que criam o novo recurso perdem participação de mercado devido aos usuários trocando de navegador depois de perceber que “funciona no navegador X”
- assim que o problema de compatibilidade for conhecido, outros fornecedores de navegador se recusam a enviar reimplantá-lo. a especificação do recurso não corresponde à realidade (“apenas uma obra de ficção”), o que é ruim para o processo de padronização.
Claro. Retrospectiva, o MooTools fez a coisa errada, mas revolucionou a Web. não os punimos, mas sim os usuários. Esses usuários não sabem o que é um moo é a melhor ferramenta. Como alternativa, podemos encontrar outra solução e os usuários podem continuar para usar a Web. A escolha é fácil.
Isso significa que APIs ruins nunca podem ser removidas da plataforma Web?
Depende. Em casos raros, recursos corrompidos podem ser removidos da Web. Mesmo descobrindo se é possível remover um recurso é um esforço muito complicado, exigindo telemetria para quantificar quantas páginas da Web mudou. Mas, quando o recurso é suficientemente inseguro, é prejudicial aos usuários, ou é usado muito raramente, isso pode ser feito.
<applet>
, <keygen>
e
showModalDialog()
são todos
exemplos de APIs inválidas que foram removidas da plataforma da Web com sucesso.
Por que simplesmente não consertamos o MooTools?
Aplicar o patch no MooTools para que ele não estenda mais objetos integrados é uma boa ideia. No entanto, isso não resolve o problema em questão. Mesmo se o MooTools estivesse para lançar uma versão com patch, todos os sites existentes que a usavam teriam que para que o problema de compatibilidade desapareça.
As pessoas não conseguem simplesmente atualizar suas cópias do MooTools?
Em um mundo perfeito, a MooTools lançaria um patch, e cada site usando o MooTools seria atualizado automaticamente no dia seguinte. Problema resolvido, certo?!
Infelizmente, isso não é realista. Mesmo que alguém, de alguma forma, identificasse o conjunto completo de sites afetados, consiga as informações de contato de todos eles, alcançar todos os proprietários de sites, e convencer todos eles a realizar a atualização (o que pode exigir a refatoração toda a base de código), todo o processo levaria anos, na melhor das hipóteses.
Tenha em mente que muitos desses sites são antigos e provavelmente não têm manutenção. Mesmo que o mantenedor ainda esteja por perto, é possível que ele não seja um um desenvolvedor Web altamente habilidoso como você. Não esperamos que todo mundo vá e mudar o site de 8 anos dele devido a um problema de compatibilidade na Web.
Como funciona o processo do TC39?
O TC39 é o comitê encarregado de desenvolver a linguagem JavaScript por meio do padrão ECMAScript.
#SmooshGate fez algumas pessoas acreditarem que "TC39 quer renomear flatten
como
smoosh
”, mas era uma piada que não foi bem comunicada externamente.
Decisões importantes, como renomear uma proposta, são deixadas de lado
por uma única pessoa e definitivamente não são tomadas da noite para o dia com base em um único
comentário no GitHub.
O TC39 opera em um processo claro de preparação para propostas de recursos.
propostas do ECMAScript e as principais alterações nelas (incluindo o método
renomeação) são discutidas durante as reuniões do TC39 e precisam ser aprovadas pelo
todo o comitê antes de se tornarem oficiais. No caso de
Array.prototype.flatten
, a proposta já passou por várias
etapas de acordo, até a etapa 3, indicando que o atributo é
prontos para serem implementados em navegadores da Web. É comum que outras especificações
problemas que podem surgir durante a implementação. Nesse caso, o mais importante
o feedback veio após a tentativa de envio: o recurso, no estado atual,
quebra a web. Problemas difíceis de prever como esses são parte da razão pela qual
o processo do TC39 não termina somente quando os navegadores fornecem um recurso.
O TC39 opera com base em consenso, o que significa que o comitê precisa concordar com quaisquer novos
mudanças. Mesmo que smoosh
tivesse sido uma sugestão séria, parece provável que
um membro do comitê se oporaria a isso em favor de um nome mais comum, como
compact
ou chain
.
A renomeação de flatten
para smoosh
, mesmo que não tenha sido uma piada,
nunca foram discutidos em uma reunião do TC39. Dessa forma, a postura oficial do TC39
este tópico é desconhecido no momento. Ninguém pode falar em nome de
todos os TC39 até chegar a um consenso na próxima reunião.
As reuniões do TC39 costumam ter a participação de pessoas com diversidade altamente antecedentes: alguns têm anos de experiência em design de linguagem de programação, enquanto outras trabalham em um navegador ou mecanismo JavaScript, e um número crescente de os atendentes estão lá para representar a comunidade de desenvolvedores JavaScript.
Como o SmooshGate foi resolvido, no fim das contas?
Durante a reunião do TC39 em maio de 2018, use o #SmooshGate.
foi resolvido oficialmente renomeando flatten
como flat
.
Array.prototype.flat
e Array.prototype.flatMap
fornecidos no V8 v6.9 e
Chrome 69.