Dia 4 — Strings

Informatica · Conteudo · publicado em 02/10/2026
Aula 1

Aspas, concatenar e interpolar

Aspas, concatenar e interpolar

Texto em JavaScript tem três delimitadores: aspa simples, aspa dupla e crase. O conteúdo é o mesmo; o que muda é o que dá para fazer com ele dentro.

DelimitadorNomeInterpola?Quando usar
'texto'aspa simplesnãotexto sem nada especial
"texto"aspa duplanãotexto que contém ', ou o contrário
` texto `crase ou template literalsimtexto com variável dentro

A crase é a única que interpola: é o que elimina a concatenação com + na maioria dos casos.

Interpolação: a crase com ${}

Dentro da crase, ${ } aceita qualquer expressão — não só variável. O que está entre as chaves é avaliado como uma linha de código e o resultado entra no texto.

const nome = 'Ana';
const idade = 30;

`Olá, ${nome}`;          // 'Olá, Ana'
`${nome} tem ${idade} anos`;
`${nome} vai fazer ${idade + 1} anos`;
`${nome.toUpperCase()}`;  // chamada de método dentro

A crase também aceita texto de várias linhas sem \n, e é a forma usada para montar trecho de HTML e consulta de banco:

`linha um
linha dois`;

Para escrever a crase com um ${} que não deve ser interpretado, escapa o cifrão: \${ }.

Concatenar com + e onde ele engana

Concatenar é juntar com +. Funciona, mas o + vira texto assim que encontra uma string, e a soma vai da esquerda para a direita — o tipo muda no meio da expressão.

'Soma: ' + 2 + 2;      // 'Soma: 22': o texto engoliu a soma
'Soma: ' + (2 + 2);    // 'Soma: 4'
`Soma: ${2 + 2}`;      // 'Soma: 4': a crase não tem o problema

Separar argumentos com vírgula dentro do console.log evita o problema inteiro: cada argumento é medido antes de virar texto, e nenhum converte o outro.

Medir o texto e escrever o que não se digita

.length devolve a quantidade de caracteres. É propriedade, não método: sem parênteses.

'JavaScript'.length;   // 10
'Café'.length;          // 4: o á com acento é um caractere
''.length;              // 0
' '.length;             // 1: espaço conta
' o '.length;           // 3

Com emoji o resultado passa do número de letras que o olho vê, porque um emoji costuma ocupar dois caracteres. Com acento não há problema: Café são quatro caracteres, quatro letras.

Escape tira o sentido especial do caractere seguinte. É a forma de escrever aspa, barra ou quebra de linha dentro do texto.

EscapeO que é
\nquebra de linha
\trecuo, como a tecla Tab
\\uma barra
\'aspa simples, dentro de aspa simples
\"aspa dupla, dentro de aspa dupla

A crase aceita \n igual, mas não precisa dele: dá para escrever a quebra de linha direto, e é mais legível em texto longo.

String() e toString()

São as duas formas de transformar valor em texto. String() funciona com qualquer valor, inclusive null e undefined; toString() precisa de um valor que tenha o método.

String(42);        // '42'
String(null);      // 'null'
String(undefined); // 'undefined'
String([1, 2]);    // '1,2'
(42).toString();   // '42'
(42).toString(2);  // '101010': 42 em binário
(255).toString(16);// 'ff': 255 em hexadecimal

Os parênteses em (42).toString() não são exagero: sem eles, o ponto seria lido como ponto decimal e o código quebraria.

toString com argumento muda a base, e não tem equivalente em PHP — é a forma de ler número em binário, octal ou hexadecimal.

Concatenar com + e interpolar com crase dão o mesmo resultado. A diferença é de manutenção: a crase deixa o texto inteiro numa linha, e o + espalha o texto em pedaços que alguém vai ter que remontar. A regra do curso é crase sempre que houver variável no meio.

Exemplo

'use strict';
// ============================================================
// AULA 1 - Aspas, concatenar e interpolar
//
// Texto em JavaScript tem três delimitadores: aspa simples, aspa
// dupla e crase. A crase é a única que interpola, ou seja, coloca
// o valor de uma variável dentro do texto sem concatenar.
// ============================================================

// As três formas. O conteúdo é o mesmo; o que muda é o delimitador.
const nome = 'Ana';
console.log('--- as três formas de escrever texto ---');
console.log('aspas simples: ' + 'Olá, ' + nome);   // com o +
console.log('aspas duplas: ' + "Olá, " + nome);    // com o +
console.log('crase com ${}: ' + `Olá, ${nome}`);   // com o ${}

// A crase aceita dentro do ${} qualquer expressão: variável,
// conta, chamada de método, chamada de função. Isso é a
// interpolação, e é o que economiza a concatenação com `+`.
const idade = 30;
const altura = 1.72;
console.log('');
console.log('--- interpolação ---');
console.log(`${nome} tem ${idade} anos`);
console.log(`${nome} vai fazer ${idade + 1} anos no mês que vem`);
console.log(`metade de ${idade} é ${idade / 2}`);
console.log(`${nome.toUpperCase()} mede ${altura.toFixed(2)} m`);

// A crase também aceita texto de várias linhas, sem \n. É a forma
// usada para montar trecho de HTML e consulta de banco.
console.log('');
console.log('--- crase com várias linhas ---');
console.log(`linha um
linha dois
linha três`);

// Concatenar com `+` funciona, mas o `+` vira texto assim que
// encontra uma string: é por isso que 1 + 1 + '2' dá '22'.
console.log('');
console.log('--- onde o + engana ---');
console.log('1 + 1 + "2" =', 1 + 1 + '2');
console.log('"2" + 1 + 1 =', '2' + 1 + 1);
console.log('"Soma: " + 2 + 2 =', 'Soma: ' + 2 + 2, '(o texto engoliu a soma)');
console.log('"Soma: " + (2 + 2) =', 'Soma: ' + (2 + 2), '(os parênteses resolveram)');
console.log('`Soma: ${2 + 2}` =', `Soma: ${2 + 2}`, '(a crase não tem o problema)');

// .length é a quantidade de caracteres. Em texto com acento ou
// emoji, o resultado passa do número de letras que o olho vê.
console.log('');
console.log('--- medir o texto ---');
console.log('"JavaScript".length =', 'JavaScript'.length);
console.log('"Café".length =', 'Café'.length, '(o a com acento conta como um caractere)');
console.log('"".length =', ''.length);
console.log('" ".length =', ' '.length, '(espaço conta)');
console.log('" o ".length =', ' o '.length, 'caracteres, e o texto tem 3 visíveis');

// Escape: a barra antes do caractere tira o sentido especial dele.
// \n quebra a linha, \t recua, \\ escreve uma barra, e \' e \" são
// as aspas do mesmo tipo que abrem o texto.
console.log('');
console.log('--- escape ---');
console.log('linha um\nlinha dois');
console.log('coluna um\tcoluna dois');
console.log("aspas simples: \\'isto entre aspas simples\\' precisa da barra antes");
console.log('barra: \\\\');

// String() e toString() são as duas formas de transformar valor em
// texto. String() funciona com qualquer valor, inclusive null e
// undefined; toString() precisa de um valor que tenha o método.
console.log('');
console.log('--- transformar em texto ---');
console.log('String(42):', String(42));
console.log('String(true):', String(true));
console.log('String(null):', String(null));
console.log('String(undefined):', String(undefined));
console.log('String([1, 2]):', String([1, 2]));
console.log('(42).toString():', (42).toString());
console.log('(42).toString(2):', (42).toString(2), '(42 em binário)');
console.log('(255).toString(16):', (255).toString(16), '(255 em hexadecimal)');
console.log('concatenar vira texto:', '' + 42, '|', 42 + '', '(o + vazio também resolve)');

Saída real

--- as três formas de escrever texto ---
aspas simples: Olá, Ana
aspas duplas: Olá, Ana
crase com ${}: Olá, Ana

--- interpolação ---
Ana tem 30 anos
Ana vai fazer 31 anos no mês que vem
metade de 30 é 15
ANA mede 1.72 m

--- crase com várias linhas ---
linha um
linha dois
linha três

--- onde o + engana ---
1 + 1 + "2" = 22
"2" + 1 + 1 = 211
"Soma: " + 2 + 2 = Soma: 22 (o texto engoliu a soma)
"Soma: " + (2 + 2) = Soma: 4 (os parênteses resolveram)
`Soma: ${2 + 2}` = Soma: 4 (a crase não tem o problema)

--- medir o texto ---
"JavaScript".length = 10
"Café".length = 4 (o a com acento conta como um caractere)
"".length = 0
" ".length = 1 (espaço conta)
" o ".length = 3 caracteres, e o texto tem 3 visíveis

--- escape ---
linha um
linha dois
coluna um	coluna dois
aspas simples: \'isto entre aspas simples\' precisa da barra antes
barra: \\

--- transformar em texto ---
String(42): 42
String(true): true
String(null): null
String(undefined): undefined
String([1, 2]): 1,2
(42).toString(): 42
(42).toString(2): 101010 (42 em binário)
(255).toString(16): ff (255 em hexadecimal)
concatenar vira texto: 42 | 42 (o + vazio também resolve)
Aula 2

Os metodos de string que o aluno procura

Os métodos de string que o aluno procura

String é imutável: nenhum método muda o texto original. Todos devolvem uma string nova, e quem guarda o resultado é quem muda de verdade.

const original = 'texto';
const modificado = original.toUpperCase();

original;      // 'texto'  — continua igual
modificado;    // 'TEXTO'  — este é o novo

Escrever 'texto'.toUpperCase(); sozinho não guarda nada. O método precisa ficar do lado direito de uma atribuição ou de um console.log.

Buscar

A diferença entre as duas famílias é esta: includes responde se o texto existe, e indexOf responde onde. A primeira devolve verdadeiro ou falso; a segunda devolve a posição, ou -1 quando não acha. Buscar texto no meio da string é o includes e o indexOf; startsWith e endsWith são os casos particulares de começo e fim.

MétodoAssinaturaDevolve
includesincludes(busca: string, posicao?: number): booleantrue ou false
indexOfindexOf(busca: string, posicao?: number): numbera posição, ou -1
lastIndexOflastIndexOf(busca: string): numbera última ocorrência, ou -1
startsWithstartsWith(busca: string, posicao?: number): booleancomeça com a busca?
endsWithendsWith(busca: string, fim?: number): booleantermina com a busca?

A distinção que mais importa: indexOf devolve posição, includes devolve verdadeiro ou falso. Os dois respondem "existe?", mas só um responde "onde?".

indexOf devolve -1 quando não acha, e -1 é um número como outro — por isso a checagem é idx !== -1 ou idx >= 0, nunca só if (idx). Posição 0 é válida e é falsa no if.

Fatiar

MétodoAssinaturaNota
sliceslice(inicio?: number, fim?: number): stringaceita índice negativo
substringsubstring(inicio: number, fim?: number): stringinverte os limites se vierem trocados
substrsubstr(inicio: number, tamanho: number): stringantigo: conta tamanho, não fim
charAtcharAt(posicao: number): stringum caractere, '' se não existe
charCodeAtcharCodeAt(posicao: number): numbero código numérico do caractere

O slice é o método do curso. Índice negativo conta de trás para frente: palavra.slice(-6) são as últimas 6 letras.

Fatiar string é o nome da operação, e o slice é o que faz: ele devolve o pedaço entre duas posições, sem mexer no original, aceitando índice negativo — palavra.slice(0, 4) para os quatro primeiros, palavra.slice(-6) para os seis últimos.

substring(4, 0) não dá string vazia: devolve do 0 ao 4, porque troca os limites. slice(4, 0) devolve '', porque respeita a ordem. substr está em modo de depreciação há anos e não deve entrar em código novo.

O fim nunca entra na conta: slice(0, 4) de 'JavaScript' é 'Java', com quatro caracteres.

charCodeAt devolve o número do caractere, e a aritmética com ele resolve o que fromCharCode faz: 'A'.charCodeAt(0) + 1 dá 66, o código de 'B'.

Transformar

MétodoAssinaturaExemplo
trimtrim(): string' Ana '.trim() → 'Ana'
toUpperCasetoUpperCase(): string'ana'.toUpperCase() → 'ANA'
toLowerCasetoLowerCase(): string'ANA'.toLowerCase() → 'ana'
replace`replace(busca: stringRegExp, troca: string): string`substitui a primeira ocorrência
replaceAllreplaceAll(busca: string, troca: string): stringsubstitui todas
repeatrepeat(quantidade: number): string'ab'.repeat(3) → 'ababab'
padStartpadStart(tamanho: number, preenchimento?: string): string'7'.padStart(3, '0') → '007'
padEndpadEnd(tamanho: number, preenchimento?: string): string'7'.padEnd(3, '.') → '7..'

replace com texto simples troca só a primeira ocorrência. 'banana'.replace('a', 'A') dá 'bAnana', não 'bAnAnA'. Para todas: replaceAll, ou replace com expressão regular em /g.

padStart preenche pela esquerda, padEnd pela direita. É a forma de alinhar número com zero à esquerda e número de casa com espaço à direita.

O encadeamento é o que torna esses métodos úteis, e a ordem conta:

entrada.trim().toLowerCase();

Cortar o espaço antes de mexer na caixa: ' Ana '.toLowerCase() deixa espaço intacto, ' Ana '.trim().toLowerCase() resolve.

Separar e juntar

São os dois lados da mesma operação: split quebra o texto e devolve array; join junta valores e devolve texto.

MétodoAssinaturaNota
split`split(separador: stringRegExp, limite?: number): string[]`separador vazio separa cada caractere
joinjoin(separador?: string): stringo inverso do split
'2026-03-15'.split('-');          // ['2026', '03', '15']
['2026', '03', '15'].join('/');    // '2026/03/15'
'abc'.split('');                  // ['a', 'b', 'c']
['Ana', 'Bia'].join(' e ');       // 'Ana e Bia'

O join é o método mais útil dos dois no trabalho do dia a dia: separador ', ' para log, '/' para caminho, ' e ' para frase. E split é a base de todo tratamento de texto: validar e-mail, cortar data, montar lista de tags.

trim, toLowerCase e includes juntos resolvem o problema que mais aparece em formulário: o campo chega com espaço nas pontas, com maiúscula erraticamente, e o includes sem cortar o espaço não acha nada. A ordem é trim(), depois caixa, depois busca.

Exemplo

'use strict';
// ============================================================
// AULA 2 - Os métodos de string que o aluno procura
//
// String é imutável: nenhum método muda o texto original. Todos
// devolvem uma string nova, e quem guarda o resultado é quem muda
// de verdade. Este exemplo cobre buscar, fatiar, transformar,
// separar e juntar.
// ============================================================

// BUSCAR: se existe, e onde está. indexOf devolve a posição ou -1;
// includes devolve true ou false.
console.log('--- buscar ---');
const email = '[email protected]';
console.log('email:', email);
console.log('indexOf("@"):', email.indexOf('@'));
console.log('indexOf("."):', email.indexOf('.'), '(o primeiro ponto)');
console.log('indexOf("+"):', email.indexOf('+'), '(-1 quando não acha)');
console.log('lastIndexOf("."):', email.lastIndexOf('.'), '(o último ponto)');
console.log('includes("@"):', email.includes('@'));
console.log('includes(" "):', email.includes(' '), '(espaço em e-mail não existe)');
console.log('startsWith("ana"):', email.startsWith('ana'));
console.log('endsWith(".br"):', email.endsWith('.br'));
console.log('startsWith("souza", 4):', email.startsWith('souza', 4),
            '(o segundo argumento é a posição inicial)');

// FATIAR: slice, substring e substr. slice aceita índice negativo
// (contar de trás para frente); substring troca os limites quando
// eles chegam invertidos; substr é antigo e conta o tamanho.
console.log('');
console.log('--- fatiar ---');
const palavra = 'JavaScript';
console.log('palavra:', palavra);
console.log('slice(0, 4):', palavra.slice(0, 4));
console.log('slice(4):', palavra.slice(4), '(até o fim)');
console.log('slice(-6):', palavra.slice(-6), '(as últimas 6 letras)');
console.log('slice(4, -6):', palavra.slice(4, -6), '(do meio, sem a ponta)');
console.log('substring(4, 0):', palavra.substring(4, 0), '(inverteu: devolve do 0 ao 4)');
console.log('substring(0, 4):', palavra.substring(0, 4));
console.log('substr(4, 6):', palavra.substr(4, 6), '(antigo: começa em 4, 6 caracteres)');
console.log('charAt(0):', palavra.charAt(0));
console.log('charAt(99):', palavra.charAt(99), '(texto vazio quando não existe)');
console.log('charCodeAt(0):', palavra.charCodeAt(0), '(código do "J")');
console.log("'A'.charCodeAt(0) + 1 =", 'A'.charCodeAt(0) + 1, '(o código de "A" virando "B")');

// TRANSFORMAR: caixa, espaço, troca e repetição. Nenhum método
// mexe no original: quem guarda o resultado é quem muda.
console.log('');
console.log('--- transformar ---');
const entrada = '  Ana Souza  ';
console.log('como chegou:', JSON.stringify(entrada), '(com espaço dos dois lados)');
console.log('trim():', JSON.stringify(entrada.trim()));
console.log('toUpperCase():', entrada.trim().toUpperCase());
console.log('toLowerCase():', 'JAVA'.toLowerCase());
console.log('replace("a", "A") só a primeira:', 'banana'.replace('a', 'A'));
console.log('replace(/-/g, "+") todas:', 'a-b-c'.replace(/-/g, '+'));
console.log('replaceAll("-", "+") todas:', 'a-b-c'.replaceAll('-', '+'));
console.log('repeat(3):', 'ab'.repeat(3));
console.log('padStart(5, "0"):', '42'.padStart(5, '0'));
console.log('padEnd(5, "0"):', '42'.padEnd(5, '0'));
console.log("'7'.padStart(3, '0') =", '7'.padStart(3, '0'), '(zero à esquerda)');
console.log("'7'.padEnd(3, '.') =", '7'.padEnd(3, '.'), '(ponto à direita)');

// O original continua igual depois de todos esses métodos: é o
// resultado novo que precisa ser guardado em uma variável.
console.log('');
console.log('--- string é imutável ---');
const original = 'texto';
const modificado = original.toUpperCase();
console.log('original:', original, '| modificado:', modificado);

// SEPARAR e JUNTAR: split vira array, join volta a ser texto. São
// os dois lados da mesma operação.
console.log('');
console.log('--- split e join ---');
const data = '2026-03-15';
console.log('data:', data);
console.log('split("-"):', data.split('-'));
console.log('quantidade de partes:', data.split('-').length);
const partes = data.split('-');
console.log('ano:', partes[0], '| mês:', partes[1], '| dia:', partes[2]);
console.log('join("/"):', partes.join('/'));
console.log('join("-"):', partes.join('-'));
console.log('split(""):', 'abc'.split(''), '(separa em cada caractere)');
console.log('join(" e "):', ['Ana', 'Bia'].join(' e '));
console.log('join(""):', ['a', 'b', 'c'].join(''), '(sem separador, junta tudo)');

// Um caso de uso que junta o dia: cortar o espaço, mexer na caixa
// e conferir o que a pessoa digitou.
console.log('');
console.log('--- trim e caixa juntos ---');
const campo = '  [email protected]  ';
const limpo = campo.trim().toLowerCase();
console.log('como chegou:', JSON.stringify(campo));
console.log('como saiu:', JSON.stringify(limpo));
console.log('tem @?', limpo.includes('@'));
console.log('domínio:', limpo.slice(limpo.indexOf('@') + 1));
console.log('começa com Joao ou Ana?', limpo.startsWith('joao') || limpo.startsWith('ana'));
console.log('só o nome, sem o domínio:', limpo.replace(/@.*/, ''));

Saída real

--- buscar ---
email: [email protected]
indexOf("@"): 9
indexOf("."): 3 (o primeiro ponto)
indexOf("+"): -1 (-1 quando não acha)
lastIndexOf("."): 20 (o último ponto)
includes("@"): true
includes(" "): false (espaço em e-mail não existe)
startsWith("ana"): true
endsWith(".br"): true
startsWith("souza", 4): true (o segundo argumento é a posição inicial)

--- fatiar ---
palavra: JavaScript
slice(0, 4): Java
slice(4): Script (até o fim)
slice(-6): Script (as últimas 6 letras)
slice(4, -6):  (do meio, sem a ponta)
substring(4, 0): Java (inverteu: devolve do 0 ao 4)
substring(0, 4): Java
substr(4, 6): Script (antigo: começa em 4, 6 caracteres)
charAt(0): J
charAt(99):  (texto vazio quando não existe)
charCodeAt(0): 74 (código do "J")
'A'.charCodeAt(0) + 1 = 66 (o código de "A" virando "B")

--- transformar ---
como chegou: "  Ana Souza  " (com espaço dos dois lados)
trim(): "Ana Souza"
toUpperCase(): ANA SOUZA
toLowerCase(): java
replace("a", "A") só a primeira: bAnana
replace(/-/g, "+") todas: a+b+c
replaceAll("-", "+") todas: a+b+c
repeat(3): ababab
padStart(5, "0"): 00042
padEnd(5, "0"): 42000
'7'.padStart(3, '0') = 007 (zero à esquerda)
'7'.padEnd(3, '.') = 7.. (ponto à direita)

--- string é imutável ---
original: texto | modificado: TEXTO

--- split e join ---
data: 2026-03-15
split("-"): [ '2026', '03', '15' ]
quantidade de partes: 3
ano: 2026 | mês: 03 | dia: 15
join("/"): 2026/03/15
join("-"): 2026-03-15
split(""): [ 'a', 'b', 'c' ] (separa em cada caractere)
join(" e "): Ana e Bia
join(""): abc (sem separador, junta tudo)

--- trim e caixa juntos ---
como chegou: "  [email protected]  "
como saiu: "[email protected]"
tem @? true
domínio: escola.edu.br
começa com Joao ou Ana? true
só o nome, sem o domínio: joao.silva