ESCOPOS, VAR, LET, CONST E SELETORES (Anotações do PRE-WORK - Bootcamp React.js do Fernando Daciuk)

ESCOPOS

Qualquer JavaScript importado na tag no navegador tem escopo global, então todos os arquivos se enxergam (herdam códigos), e isto é perigoso.

Função

As funções criam um novo escopo. Então o problema de escopo global no JavaScript foi resolvido inicialmente com IIFE, ou expressão de função imediatamente invocada:

(function (){
   'use strict'
   Todo o código dentro do arquivo fica dentro desta função.
})()

Módulo

Para substituir o IIFE foi desenvolvido em 2015, e implementado no ES6, o escopo de módulo, um atributo dentro da tag <script type="module">. Os arquivos agora podem se enxergar usando imports/exports:

arquivo2.js

export const nome_variavel = valor;
// ou 
export { nome_variavel }

arquivo1.js

import {nome_variavel} from "./arquivo1"; // não precisa usar a extensão .js

Mais em: https://blog.da2k.com.br/2019/02/25/ecmascript-modules-modulos-nativos-no-javascript

Bloco

Um bloco de código é um bloco entre chaves {} e algumas estruturas JavaScript geram escopo de bloco por usar um bloco de código: Estruturas condicionais como if e switch, e estruturas de repetição como for, while, do while, geram bloco de código. Estas estruturas não são expressões, por que elas não retornam um valor, apenas verificam e percorrem valores.

VAR, LET E CONST

Use preferencialmente o const ao invés do let e o let ao invés do var. O var gera hoisting/içamento que é o poder de usar variavies antes da declaração ou fora do escopo de bloco (fora da função ou condição), o que pode ocasionar resultados inesperados e ruins, algo que o let previne e não permite. O let é de escopo local: só é acessado no mesmo lugar em que foi declarado. São enxergadas pelas funções dentro de seu bloco mas não são enxergadas fora da função em que foi declarada.

Mas a maior parte do tempo a mutabilidade de valores pode ser perigosa e também ocasionar resultados inesperados, algo que a const previne pois seus valor é constante: nunca muda.

SELETORES

Os seletores getElementsByClass, getElementsByTagName, getElementById retornam uma HTMLCollection, elas são vivas e atualizam novos valores dinamicamente o que também pode gerar efeitos colaterais não desejados, por isso foi desenvolvido os novos seletores querySelector e querySelectorAll que retornam uma NodeList que não atualiza os valores sem antes fazer uma nova seleção.

As querySelector são seletores JavaScript que utilizam os mesmo seletores do CSS mas não é recomendado selecionar classes e id porque elas são mutáveis: além de ter que mudar o nome no arquivo HTML e no arquivo CSS teria ainda que mudar os nomes nos arquivos JavaScript. Por isso em 2010 surgiram os atributos data nas tags HTML5 que também previnem o escopo global das id (window.nome_de_alguma_ID

Então, classes são usadas como preferencialmente como seletores no CSS, os atributo data-nome-do-atributo são utilizados como seletores no JavaScript e as id somente para acessibilidade (dar foco em inputs, navegação interna de páginas/âncoras, etc). Modo de usar os atributo data no HTML:

<a href="#" data-js="link">

Modo de utilizar os atributo data no JavaScript:

const link = document.querySeletor(‘[data-js="link"]’);

Sobre os data attributes, o propósito deles é simplesmente de armazenar dados customizados associados a um elemento, quando não há nenhum outro atributo que sirva. Isso é descrito pela própria especificação do HTML:

Custom data attributes are intended to store custom data, state, annotations, and similar, private to the page or application, for which there are no more appropriate attributes or elements.

No mesmo link tem alguns exemplos de uso, e tem outros no tutorial da MDN.

Ou seja, os data attributes não foram criados para substituir id e class (que foi o que eu entendi do seu texto). Inclusive, esta distinção sobre classes serem usadas no CSS e id somente para acessibilidade vai contra a especificação do HTML, que lista os usos do atributo id:

An element's unique identifier can be used for a variety of purposes, most notably as a way to link to specific parts of a document using fragments, as a way to target an element when scripting, and as a way to style a specific element from CSS.

Repare que ele lista os usos em scripts (ou seja, inclui querySelector) e CSS. Claro que data attributes também podem ser usados em JS e CSS, mas não quer dizer que eles substituem ou corrigem alguma falha do id e class: simplesmente são atributos diferentes, cada um com seu propósito.

Enfim, eu vejo a busca por atributos como uma alternativa quando não há opção melhor (elemento não tem id ou nenhuma outra característica mais específica), ou quando eu realmente preciso somente de elementos que possuem tal atributo. Mas nunca como substituto de id ou class. Eu prefiro usar o seletor mais específico possível para cada caso. E se um elemento é tão importante a ponto de eu precisar fazer algo específico com ele, talvez seja o caso dele ter um id próprio (ou class, caso seja um grupo de elementos com o mesmo propósito, por exemplo).


Aliás, se o id ou class dos elementos está mudando tanto a ponto de "justificar" o uso de data attributes, é sinal de que tem algo errado aí, pois estes dados não deveriam mudar tanto assim.

Geralmente quando o id e class mudam bastante é nos casos de frameworks que os geram dinamicamente, mas aí esses frameworks costumam fornecer outras maneiras de acessar estes elementos. Tirando isso, esses atributos deveriam ser mais estáveis (se não são, isso é um sintoma e o problema é outro, e a solução não é usar outros atributos).


E vale lembrar que getElementById e querySelector retornam apenas um elemento (ou null caso não seja encontrado). Os demais sim, retornam coleções.

Quanto a usar const, let e var, não é necessariamente questão de "preferência", e sim de saber as características de cada um e usar conforme o caso (por exemplo, em browsers velhos só o var funciona, às vezes vc quer/precisa que faça o hoisting, etc). Outro ponto é que const também tem armadilhas.

Fernando Daciuk deveria se envergonhar por ensinar esse monte de baboseira. Post horrível, com informações erradas. Dá pra fazer uma lista do que está errado aqui.