Pular para o conteúdo principal

ES2015, ES2016 e além

· Leitura de 9 minutos
a equipe do V8, entusiastas do ECMAScript

A equipe do V8 dá grande importância à evolução do JavaScript em uma linguagem cada vez mais expressiva e bem definida que torna fácil escrever aplicações web rápidas, seguras e corretas. Em junho de 2015, a especificação ES2015 foi ratificada pelo comitê de padrões TC39, tornando-se a maior atualização única da linguagem JavaScript. Novos recursos incluem classes, funções de seta, promessas, iteradores / geradores, proxies, símbolos conhecidos e adicionais açúcares sintáticos. O TC39 também aumentou a cadência de novas especificações e lançou o rascunho candidato para ES2016 em fevereiro de 2016, que será ratificado neste verão. Embora não seja tão expansivo quanto a atualização para ES2015 devido ao ciclo de lançamento mais curto, o ES2016 notavelmente introduz o operador de exponenciação e Array.prototype.includes.

Hoje alcançamos um marco importante: o V8 suporta ES2015 e ES2016. Você pode usar os novos recursos da linguagem hoje no Chrome Canary, e eles serão lançados como padrão no Chrome 52.

Dada a natureza de uma especificação em evolução, as diferenças entre vários tipos de testes de conformidade e a complexidade de manter a compatibilidade com a web, pode ser difícil determinar quando uma certa versão do ECMAScript é considerada totalmente suportada por um mecanismo de JavaScript. Leia mais para entender por que o suporte à especificação é mais complexo do que números de versão, por que as chamadas de cauda apropriadas ainda estão em discussão e quais os avisos permanecem em jogo.

Uma especificação em evolução

Quando o TC39 decidiu publicar atualizações mais frequentes na especificação do JavaScript, a versão mais atualizada da linguagem tornou-se a versão principal, em rascunho. Embora versões da especificação ECMAScript ainda sejam produzidas anualmente e ratificadas, o V8 implementa uma combinação da versão mais recentemente ratificada (por exemplo, ES2015), certos recursos que estão próximos o suficiente da padronização para serem seguros de implementar (por exemplo, o operador de exponenciação e Array.prototype.includes() do rascunho candidato do ES2016), e uma coleção de correções de bugs e emendas de compatibilidade da web de rascunhos mais recentes. Parte da justificativa para tal abordagem é que as implementações de linguagem nos navegadores devem corresponder à especificação, mesmo que seja a especificação que precise ser atualizada. De fato, o processo de implementação de uma versão ratificada da especificação frequentemente descobre muitas das correções e esclarecimentos que constituem a próxima versão da especificação.

Partes atualmente disponíveis da especificação ECMAScript em evolução

Por exemplo, ao implementar o sinalizador sticky do RegExp do ES2015, a equipe do V8 descobriu que a semântica da especificação ES2015 quebrava muitos sites existentes (incluindo todos os sites que usavam versões 2.x.x da popular biblioteca XRegExp). Como a compatibilidade é um dos pilares da web, engenheiros das equipes do V8 e do Safari JavaScriptCore propunham uma emenda à especificação RegExp para corrigir a quebra, que foi acordada pelo TC39. A emenda não aparecerá em uma versão ratificada até o ES2017, mas ainda é parte da linguagem ECMAScript e a implementamos para lançar o sinalizador sticky do RegExp.

O refinamento contínuo da especificação de linguagem e o fato de que cada versão (incluindo o rascunho que ainda será ratificado) substitui, emenda, e esclarece versões anteriores tornam complicado entender as complexidades por trás do suporte ao ES2015 e ES2016. Embora seja impossível afirmar de forma sucinta, talvez seja mais preciso dizer que o V8 suporta conformidade com o “rascunho contínuo mantido da futura especificação ECMAScript”!

Medindo conformidade

Com o objetivo de compreender essa complexidade das especificações, existem várias maneiras de medir a compatibilidade do mecanismo JavaScript com o padrão ECMAScript. A equipe do V8, assim como outros fornecedores de navegadores, utiliza o conjunto de testes Test262 como padrão de excelência de conformidade com o rascunho continuamente atualizado do futuro padrão ECMAScript. Este conjunto de testes é continuamente atualizado para corresponder à especificação e fornece 16.000 testes funcionais distintos para todos os recursos e casos limite que compõem uma implementação compatível e em conformidade do JavaScript. Atualmente, o V8 passa aproximadamente 98% do Test262, e os 2% restantes correspondem a uma pequena quantidade de casos limite e recursos futuros do ES que ainda não estão prontos para serem lançados.

Como é difícil revisar o número enorme de testes do Test262, existem outros testes de conformidade, como a tabela de compatibilidade Kangax. A tabela Kangax torna fácil verificar se um recurso específico (como funções flecha) foi implementado em um mecanismo dado, mas não testa todos os casos limite que o Test262 cobre. Atualmente, o Chrome Canary tem um índice de 98% na tabela Kangax para ES2015 e 100% nas seções da Kangax correspondentes ao ES2016 (por exemplo, as seções rotuladas como “2016 features” e “2016 misc” na aba ESnext).

Os 2% restantes dos testes da tabela Kangax para ES2015 chamadas de cauda adequadas, um recurso que foi implementado no V8, mas intencionalmente desativado no Chrome Canary devido a preocupações pendentes sobre a experiência do desenvolvedor detalhadas abaixo. Com a flag “Experimental JavaScript features” ativada, que força este recurso, o Canary chega a 100% na tabela Kangax completa para ES2015.

Chamadas de cauda adequadas

As chamadas de cauda adequadas foram implementadas, mas ainda não lançadas, dado que uma alteração no recurso está atualmente em discussão no TC39. O ES2015 especifica que chamadas de funções em modo estrito em posição de cauda nunca devem causar um estouro de pilha. Embora isso seja uma garantia útil para certos padrões de programação, a semântica atual apresenta dois problemas. Primeiro, como a eliminação de chamada de cauda é implícita, pode ser difícil para os programadores identificarem quais funções estão realmente em posição de cauda. Isso significa que os desenvolvedores podem não descobrir tentativas mal colocadas de chamadas de cauda em seus programas até que sobrecarreguem a pilha. Segundo, implementar chamadas de cauda adequadas exige remover quadros de chamada da cauda da pilha, o que faz perder informações sobre o fluxo de execução. Isso, por sua vez, tem duas consequências:

  1. Torna mais difícil entender durante a depuração como a execução chegou a um determinado ponto, pois a pilha contém descontinuidades, e
  2. error.stack contém menos informações sobre o fluxo de execução, o que pode comprometer software de telemetria que coleta e analisa erros no lado do cliente.

Implementar uma pilha sombra pode melhorar a legibilidade das pilhas de chamada, mas as equipes do V8 e do DevTools acreditam que a depuração é mais fácil, confiável e precisa quando a pilha exibida durante a depuração é completamente determinística e sempre corresponde ao estado real da pilha da máquina virtual. Além disso, uma pilha sombra é muito cara em termos de desempenho para ser ativada o tempo todo.

Por essas razões, a equipe do V8 apoia fortemente a indicação de chamadas de cauda adequadas por uma sintaxe especial. Há uma proposta pendente no TC39 chamada chamadas de cauda sintáticas para especificar esse comportamento, co-patrocinada por membros do comitê da Mozilla e Microsoft. Implementamos e preparamos chamadas de cauda adequadas conforme especificado no ES2015 e começamos a implementar chamadas de cauda sintáticas conforme especificado na nova proposta. A equipe do V8 planeja resolver a questão na próxima reunião do TC39 antes de lançar chamadas de cauda adequadas implícitas ou chamadas de cauda sintáticas por padrão. Você pode testar cada versão enquanto isso, usando as flags do V8 --harmony-tailcalls e --harmony-explicit-tailcalls. Atualização: Estas flags foram removidas.

Módulos

Uma das promessas mais empolgantes do ES2015 é o suporte para módulos JavaScript para organizar e separar diferentes partes de uma aplicação em namespaces. O ES2015 especifica as declarações import e export para módulos, mas não como os módulos são carregados em um programa JavaScript. No navegador, o comportamento de carregamento foi recentemente especificado através de <script type="module">. Embora seja necessário trabalho adicional de padronização para especificar APIs avançadas de carregamento dinâmico de módulos, o suporte do Chromium para tags de script de módulo já está em desenvolvimento. Você pode acompanhar o trabalho de implementação no bug de lançamento e ler mais sobre ideias experimentais de API de carregadores no repositório whatwg/loader.

ESnext e além

No futuro, os desenvolvedores podem esperar que as atualizações do ECMAScript sejam menores, mais frequentes e com ciclos de implementação mais curtos. A equipe do V8 já está trabalhando para trazer recursos futuros como palavras-chave async/await, Object.values / Object.entries, String.prototype.{padStart,padEnd} e lookbehind de RegExp para o tempo de execução. Volte para conferir mais atualizações sobre o progresso da nossa implementação do ESnext e as otimizações de desempenho para recursos existentes do ES2015 e ES2016+.

Nos empenhamos em continuar a evolução do JavaScript, encontrando o equilíbrio certo entre a implementação antecipada de novos recursos, garantindo compatibilidade e estabilidade com a web existente, e fornecendo ao TC39 feedback de implementação sobre preocupações de design. Estamos ansiosos para ver as experiências incríveis que os desenvolvedores criarão com esses novos recursos.