Strings: métodos essenciais e template literals

1. Introdução às Strings em JavaScript

Strings em JavaScript representam sequências de caracteres e podem ser criadas usando aspas simples ('), aspas duplas (") ou crases (`). Embora o comportamento básico seja o mesmo, as crases habilitam recursos avançados como template literals, que veremos adiante.

const simples = 'Olá, mundo!';
const duplas = "JavaScript é incrível";
const crases = `Template literals`;

Um conceito fundamental é a imutabilidade das strings: uma vez criada, uma string nunca pode ser alterada. Qualquer método que pareça modificar a string na verdade retorna uma nova string. Isso impacta a performance quando muitas operações são realizadas em loops.

let texto = 'abc';
texto[0] = 'x'; // Não modifica a string original
console.log(texto); // 'abc'

A propriedade length retorna o número de caracteres, e podemos acessar caracteres individuais com colchetes ou métodos específicos:

const frase = 'JavaScript';
console.log(frase.length); // 10
console.log(frase[0]);     // 'J'
console.log(frase[frase.length - 1]); // 't'

2. Métodos de Busca e Extração

Para localizar substrings dentro de uma string, temos três métodos essenciais:

const texto = 'Aprenda JavaScript com Node.js e React';

console.log(texto.indexOf('JavaScript')); // 8
console.log(texto.lastIndexOf('e'));      // 30
console.log(texto.includes('React'));     // true

Para extrair partes da string, slice(), substring() e substr() são as opções:

const email = 'usuario@exemplo.com';
console.log(email.slice(0, 7));       // 'usuario'
console.log(email.substring(8));      // 'exemplo.com'
console.log(email.substr(0, 7));      // 'usuario' (obsoleto, evitar)

O método at() (ES2022) oferece uma sintaxe mais limpa para acessar caracteres, especialmente no final da string:

const palavra = 'Node.js';
console.log(palavra.at(0));  // 'N'
console.log(palavra.at(-1)); // 's' - último caractere
console.log(palavra.charAt(3)); // 'e' (alternativa clássica)

3. Métodos de Transformação e Formatação

Transformar e normalizar strings é uma tarefa comum em aplicações reais:

const entrada = '  JavaScript é Poderoso!  ';
console.log(entrada.trim());          // 'JavaScript é Poderoso!'
console.log(entrada.toLowerCase());   // '  javascript é poderoso!  '
console.log(entrada.toUpperCase());   // '  JAVASCRIPT É PODEROSO!  '

Para substituições, replace() e replaceAll() são indispensáveis:

const frase = 'Gato, gato, GATO';
console.log(frase.replace('gato', 'cachorro'));      // 'Gato, cachorro, GATO'
console.log(frase.replaceAll(/gato/gi, 'cachorro')); // 'cachorro, cachorro, cachorro'

Para alinhamento e formatação, padStart() e padEnd() são úteis:

const numero = '42';
console.log(numero.padStart(5, '0')); // '00042'
console.log('React'.padEnd(10, '-')); // 'React-----'

4. Métodos de Divisão e Combinação

split() converte uma string em array, enquanto join() faz o inverso:

const csv = 'João, Maria, Pedro';
const nomes = csv.split(', '); // ['João', 'Maria', 'Pedro']
console.log(nomes.join(' | ')); // 'João | Maria | Pedro'

Para concatenação, o operador + e concat() são equivalentes, mas + é mais idiomático:

const saudacao = 'Olá, ' + 'mundo!';
const alternativa = 'Olá, '.concat('mundo!');
console.log(saudacao); // 'Olá, mundo!'

5. Template Literals: Sintaxe e Interpolação

Template literals revolucionaram a forma como trabalhamos com strings. Usando crases e ${}, podemos interpolar variáveis e expressões complexas:

const nome = 'Ana';
const idade = 28;
const mensagem = `Meu nome é ${nome} e tenho ${idade} anos.`;
console.log(mensagem); // 'Meu nome é Ana e tenho 28 anos.'

Expressões mais complexas são perfeitamente válidas:

const preco = 49.90;
const desconto = 0.1;
const total = `Total: R$ ${(preco * (1 - desconto)).toFixed(2)}`;
console.log(total); // 'Total: R$ 44.91'

As vantagens sobre concatenação tradicional incluem legibilidade, manutenibilidade e prevenção de erros comuns de espaçamento.

6. Template Literals: Strings Multilinha e Tagged Templates

Criar strings multilinha nunca foi tão fácil:

const poema = `
Rosas são vermelhas,
Violetas são azuis,
JavaScript é demais,
E você também!
`;
console.log(poema);

Tagged templates permitem processar templates com funções customizadas:

function destacar(strings, ...valores) {
  return strings.reduce((resultado, str, i) => {
    return `${resultado}${str}<strong>${valores[i] || ''}</strong>`;
  }, '');
}

const linguagem = 'JavaScript';
const framework = 'React';
const html = destacar`Aprendendo ${linguagem} com ${framework}`;
console.log(html); // 'Aprendendo <strong>JavaScript</strong> com <strong>React</strong>'

String.raw() é um tagged template nativo que preserva escapes literais:

const caminho = String.raw`C:\Users\Nome\Documentos`;
console.log(caminho); // 'C:\Users\Nome\Documentos'

7. Métodos Modernos e Expressões Regulares

Métodos como startsWith(), endsWith() e repeat() são extremamente úteis:

const url = 'https://react.dev';
console.log(url.startsWith('https')); // true
console.log(url.endsWith('.dev'));    // true
console.log('Ha! '.repeat(3));        // 'Ha! Ha! Ha! '

Combinando métodos de string com expressões regulares:

const texto = 'Contato: contato@exemplo.com ou suporte@teste.org';
const emails = texto.match(/[\w.-]+@[\w.-]+\.\w+/g);
console.log(emails); // ['contato@exemplo.com', 'suporte@teste.org']

console.log(texto.search(/@/)); // 9 (posição do primeiro @)

// matchAll() retorna um iterador com detalhes
for (const match of texto.matchAll(/(\w+)@(\w+)/g)) {
  console.log(`Usuário: ${match[1]}, Domínio: ${match[2]}`);
}

Boas práticas incluem evitar regex complexas quando métodos simples resolvem e sempre testar padrões com ferramentas como regex101.com.

8. Aplicações Práticas em Node.js e React

Validação e sanitização em Node.js:

function sanitizarEntrada(texto) {
  return texto
    .trim()
    .replace(/<[^>]*>/g, '') // Remove tags HTML
    .slice(0, 100);           // Limita tamanho
}

const entradaUsuario = '  <script>alert("xss")</script>Olá!  ';
console.log(sanitizarEntrada(entradaUsuario)); // 'Olá!'

Renderização condicional em React com template literals:

function StatusUsuario({ status, nome }) {
  const classes = `status ${status === 'online' ? 'verde' : 'cinza'}`;

  return (
    <div className={classes}>
      {`${nome} está ${status === 'online' ? '🟢 online' : '🔴 offline'}`}
    </div>
  );
}

Formatação de dados para internacionalização:

function formatarData(data) {
  const opcoes = { day: '2-digit', month: 'long', year: 'numeric' };
  return new Intl.DateTimeFormat('pt-BR', opcoes).format(data);
}

console.log(formatarData(new Date())); // '10 de março de 2025'

Referências