O JavaScript vem se desenvolvendo muito rapidamente nos últimos anos. Isso é especialmente verdade no período após o lançamento do padrão ES6 em 2015. Desde então, muitos recursos excelentes apareceram no idioma. Muito novo foi proposto para inclusão no padrão ES2020. Uma lista final de recursos já foi formada, cuja aparência pode ser esperada no padrão após sua aprovação. Esta é uma boa notícia para todos os entusiastas do JS. O autor do artigo, cuja tradução estamos publicando hoje, diz que entre essas oportunidades há aquelas com as quais ele está especialmente satisfeito. Antes de aparecerem, era muito mais difícil para ele escrever código nas situações em que são aplicáveis. Segundo ele, se eles tivessem aparecido no idioma anteriormente, teriam poupado muito tempo e esforço.
Correntes opcionais
O encadeamento opcional é, para mim, um dos recursos mais interessantes do padrão ES2020. Eu escrevi muitos programas nos quais esse recurso seria extremamente útil. As cadeias opcionais permitem organizar o acesso seguro a propriedades profundamente incorporadas de objetos sem a necessidade de verificar a existência de cada um deles. Veja como esse recurso funciona.Primeiro, observe o código que precisava ser escrito antes do advento das cadeias opcionais.Before Código antes do aparecimento de cadeias opcionais
const user = {
firstName:"Joseph",
lastName:"Kuruvilla",
age:38,
address:{
number:"239",
street:"Ludwig Lane",
city:"Chennai",
zip:"600028",
prop1:{
prop2:{
prop3:{
prop4:{
value:'sample'
}
}
}
}
}
}
if(user && user.address){
console.log(user.address.zip);
}
if(user && user.address && user.address.prop1 && user.address.prop1.prop2 && user.address.prop1.prop2.prop3 && user.address.prop1.prop2.prop3.prop4){
console.log(user.address.prop1.prop2.prop3.prop4.value);
}
console.log(user.address.prop102.po);
Como você pode ver, para evitar a ocorrência de erros, parece Cannot read property 'po' of undefined
que é necessário, em cada nível de aninhamento, verificar as propriedades quanto à sua existência. Com um aumento na profundidade do aninhamento de entidades, o número de propriedades verificadas também aumenta. Isso significa que o próprio programador precisa escrever um código que o proteja de propriedades que, quando acessadas, podem executar os valores de null
ou undefined
.After Código após o aparecimento de cadeias opcionais
Escrever código como o que acabamos de revisar tornou muito mais fácil com o advento de cadeias opcionais. Para organizar o trabalho seguro com propriedades profundamente incorporadas de objetos, basta usar o operador ?.
. Isso evita a necessidade de verificar independentemente os valores em null
e undefined
.Aqui está o que parece:const user = {
firstName:"Joseph",
lastName:"Kuruvilla",
age:38,
address:{
number:"239",
street:"Ludwig Lane",
city:"Chennai",
zip:"600028",
prop1:{
prop2:{
prop3:{
prop4:{
value:'sample'
}
}
}
}
}
}
console.log(user?.address?.zip);
console.log(user?.address?.prop1?.prop2?.prop3?.prop4?.value);
console.log(user?.address?.prop102?.po);
Bem, não está bem? Graças a essa inovação, o ES2020 tornou possível eliminar um grande número de linhas de código.Validando apenas valores nulos e indefinidos
Verificar valores apenas em null
e undefined
(Nullish Coalescing) é uma daquelas características que realmente me encantaram, mesmo quando as possibilidades estavam no estágio de proposta. Muitas vezes me deparei com a necessidade de escrever funções especializadas para realizar as verificações apropriadas.Sabe-se que o JavaScript tem significados "falsos" e "verdadeiros". Agora podemos dizer que valores "zero" foram adicionados a eles. Esses valores incluem null
e undefined
. Com termos de JavaScript de "falso" são strings vazias, o número 0, os valores undefined
, null
, false
, NaN
. Ou seja, por exemplo, uma certa expressão para verificar o valor de "falsidade" funcionará em uma sequência vazia e no valorundefined
e muito mais sobre o que. E a expressão para verificar o valor de "zero" retornará true
apenas para null
e undefined
. Talvez essa oportunidade não pareça tão maravilhosa para você pessoalmente, mas, de fato, é muito, muito importante.Vejamos alguns exemplos.Code O código até a capacidade de verificar valores apenas em nulos e indefinidos
Recentemente, eu estava trabalhando em um projeto no qual precisava implementar a funcionalidade de alternar entre temas claros e escuros. Ao mesmo tempo, tive que verificar o estado do controle, descobrir se ele corresponde ao valor de true
ou false
. Se o usuário não definiu nenhum valor, por padrão, ele deve ser igual true
. Aqui está como eu resolvi esse problema antes da possibilidade de verificar valores apenas em null
e undefined
:const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
if (darkModePreference || darkModePreference === false) {
return darkModePreference
}
return true
}
getUserDarkModePreference(darkModePreference1)
getUserDarkModePreference(darkModePreference2)
getUserDarkModePreference(darkModePreference3)
getUserDarkModePreference(darkModePreference4)
After Código após a possibilidade de verificar valores apenas em nulos e indefinidos
Depois que esse recurso aparecer no idioma para verificação null
e undefined
operador suficiente ??
. Nesse caso, você pode fazer sem um operador condicional if
:const darkModePreference1 = true
const darkModePreference2 = false
const darkModePreference3 = undefined
const darkModePreference4 = null
const getUserDarkModePreference = (darkModePreference) => {
return darkModePreference ?? true;
}
getUserDarkModePreference(darkModePreference1)
getUserDarkModePreference(darkModePreference2)
getUserDarkModePreference(darkModePreference3)
getUserDarkModePreference(darkModePreference4)
Aqui acontece o seguinte: se a variável darkModePreference
contiver um valor "zero", o valor será retornado true
. Isso facilita a escrita do código, é compacto e fácil de entender.Importações dinâmicas
As importações dinâmicas contribuem para um desempenho mais eficiente dos aplicativos. Essa tecnologia permite importar arquivos JS dinamicamente, na forma de módulos, sem envolver ferramentas adicionais. Além disso, se o módulo não for necessário, ele não será importado. Antes do ES2020, os módulos eram importados, independentemente de serem usados pelo aplicativo ou não.Por exemplo, suponha que precisamos implementar a funcionalidade de carregar um determinado arquivo no formato PDF.Considere, como sempre, as opções antigas e novas para resolver esse problema.Before Código antes do suporte para importações dinâmicas
Com base na situação real, podemos esperar que a capacidade de baixar materiais em formato PDF não seja usada por todos os visitantes da página. Mas o módulo correspondente, de qualquer maneira, precisa ser importado para o código. Isso significa que o módulo, necessário ou não, será carregado quando a página carregar.import { exportAsPdf } from './export-as-pdf.js'
const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', exportAsPdf);
Isso cria uma carga adicional no sistema, que pode ser facilitada usando o carregamento lento dos módulos. Isso pode ser feito com a ajuda da tecnologia de separação de código, disponível no webpack ou em outros carregadores de módulos (e seu uso por si só significa desperdício de uma certa quantidade de recursos do sistema).Mas agora, graças ao ES2020, temos uma maneira padrão de carregar dinamicamente módulos, o que nos permite prescindir de empacotadores.After Código após o aparecimento do suporte para importações dinâmicas
const exportPdfButton = document.querySelector('.exportPdfBtn');
exportPdfButton.addEventListener('click', () => {
import('./export-as-pdf.js')
.then(module => {
module.exportAsPdf()
})
.catch(err => {
})
})
Como você pode ver, agora você pode organizar o carregamento lento dos módulos carregando somente quando precisar do módulo apropriado. Isso reduz a carga do sistema e aumenta a velocidade de carregamento da página.Construir Promise.allSettled
Se você precisa executar alguma ação somente se todas as promessas foram resolvidos com êxito, você pode usar o método Promise.all()
. É verdade que este método tem uma desvantagem. O método lançará um erro se pelo menos uma promessa passada a ele for rejeitada. Isso significa que a ação necessária não será executada até que todas as promessas sejam resolvidas com sucesso.Você pode não precisar disso. Talvez o seguinte cenário seja o seu caso: “O resultado não é importante para mim. Eu preciso que o código seja executado após a conclusão de todas as promessas. ” Nesse caso, o método é útil para você Promise.allSettled()
. A promessa correspondente é resolvida com sucesso somente após a conclusão de outras promessas. Não importa se eles funcionaram com ou sem êxito.▍ Código usando a construção Promise.all
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Data release"),
Promise.reject(new Error('Something went wrong'))];
Promise.all(PromiseArray)
.then(data => console.log('all resolved! here are the resolve values:', data))
.catch(err => console.log('got rejected! reason:', err))
Aparentemente, Promise.all
ocorre um erro após a rejeição de uma das promessas transferidas para ele.▍ Código que usa a construção Promise.allSettled
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Data release"),
Promise.reject(new Error('Something went wrong'))];
Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));
E aqui, embora algumas das promessas sejam rejeitadas, ele Promise.allSettled
retorna os resultados emitidos por todas as promessas transferidas para ele.Outros recursos notáveis
Type Tipo de dados BigInt
O novo tipo de dados BigInt
permite que você trabalhe com números cujo tamanho excede o tamanho dos números com os quais você poderia trabalhar em JavaScript antes de aparecer ( pow(2,53)-1
). É verdade que esse tipo de dado não é compatível com o que estava no idioma anterior. O padrão IEEE 754, que é a base para trabalhar com números em JavaScript, não suporta os números possíveis de trabalhar comBigInt
▍ Método String.prototype.matchAll
O método String.prototype.matchAll()
está relacionado a expressões regulares. Ele retorna um iterador, permitindo que você trabalhe com todas as correspondências encontradas em uma string usando uma expressão regular , incluindo grupos .▍ Propriedade global globalThis
A propriedade global globalThis
mantém uma referência ao objeto global correspondente ao ambiente em que o código é executado. No navegador, o objeto global é representado pelo objeto window
. No Node.js, este é um objeto global
. Nos trabalhadores da Web, este é um objeto self
.Quais inovações você mais gosta no ES2020?