O tipo de JavaScript para representar texto é a string. Uma string é uma sequência imutável ordenada de valores de 16 bits, cada um dos quais normalmente representa um caractere Unicode. O comprimento de uma string é o número de valores de 16 bits que ela contém. As strings de JavaScript (e seus arrays) usam indexação baseada em zero: o primeiro valor de 16 bits está na posição 0, o segundo na posição 1 e assim por diante. A string vazia é a string de comprimento 0. JavaScript não tem um tipo especial que representa um único elemento de uma string. Para representar um único valor de 16 bits, basta usar uma string com comprimento 1.
CARACTERES, CODEPOINTS E STRINGS JAVASCRIPT
O JavaScript usa a codificação UTF-16 do conjunto de caracteres Unicode e as strings de JavaScript são sequências de valores de 16 bits não assinados. Os caracteres Unicode mais comumente usados (aqueles do “plano multilíngue básico”) têm pontos de código que cabem em 16 bits e podem ser representados por um elemento de uma string. Os caracteres Unicode cujos pontos de código não cabem em 16 bits são codificados usando as regras do UTF-16 como uma sequência (conhecida como “par substituto”) de dois valores de 16 bits. Isso significa que uma string JavaScript de comprimento 2 (dois valores de 16 bits) pode representar apenas um único caractere Unicode:
let euro = "€";
let love = "❤";
euro.length // => 1: este caractere tem um elemento de 16 bits
love.length // => 2: A codificação UTF-16 de ❤ é "\ud83d \udc99"
A maioria dos métodos de manipulação de string definidos pelo JavaScript opera em valores de 16 bits, não em caracteres. Eles não tratam pares substitutos de maneira especial, não realizam normalização da sequência e nem mesmo garantem que uma sequência seja UTF-16 bem formada.
No ES6, entretanto, as strings são iteráveis e, se você usar o loop for/of ou ...(operador spread) com uma string, ele iterará os caracteres reais da string, não os valores de 16 bits.
Literais de String
Para incluir uma string em um programa JavaScript, simplesmente coloque os caracteres da string dentro de um par correspondente de aspas simples ou duplas ou crases ('ou "ou`). Caracteres de aspas duplas e crases podem estar contidos em strings delimitadas por simples- citar caracteres e de forma semelhante para strings delimitadas por aspas duplas e crases. Aqui estão alguns exemplos de literais de string:
"" // A string vazia: tem zero caracteres
'testing'
"3.14"
'name="myform"'
"Wouldn't you prefer O'Reilly's book?"
"τ is the ratio of a circle's circumference to its radius"
`"She said 'hi'", he said.`
Strings delimitadas com crases são um recurso do ES6 e permitem que expressões JavaScript sejam incorporadas (ou interpoladas) no literal de string.
As versões originais do JavaScript exigiam que literais de string fossem gravados em uma única linha e é comum ver o código JavaScript que cria strings longas concatenando strings de linha única com o operador +. No ES5, entretanto, você pode quebrar um literal de string em várias linhas, terminando cada linha, mas a última com uma barra invertida ( \ ). Nem a barra invertida nem o terminador de linha que a segue fazem parte do literal da string. Se você precisar incluir um caractere de nova linha em um literal de string entre aspas simples ou duplas, use a sequência de caracteres \ n (documentada na próxima seção). A sintaxe de crase ES6 permite que as strings sejam quebradas em várias linhas e, neste caso, os terminadores de linha são parte do literal da string:
// Uma string representando 2 linhas escritas em uma linha:
'two\nlines'
// Uma string de uma linha escrita em 3 linhas:
"one\
long\
line"
// Uma string de duas linhas escrita em duas linhas:
`the newline character at the end of this line
is included literally in this string`
Observe que, ao usar aspas simples para delimitar suas strings, você deve ter cuidado com as contrações e possessivas em inglês, como can can't e O’Reilly’s. Como o apóstrofo é igual ao caractere de aspas simples, você deve usar o caractere de barra invertida ( \ ) para “escapar” de quaisquer apóstrofos que apareçam em strings entre aspas simples.
Na programação JavaScript do lado do cliente, o código JavaScript pode conter strings de código HTML e o código HTML pode conter strings de código JavaScript. Como o JavaScript, o HTML usa aspas simples ou duplas para delimitar suas strings. Portanto, ao combinar JavaScript e HTML, é uma boa ideia usar um estilo de aspas para JavaScript e o outro estilo para HTML. No exemplo a seguir, a string “Obrigado” é colocada entre aspas simples em uma expressão JavaScript, que é então colocada entre aspas em um atributo de manipulador de eventos HTML:
<button onclick="alert('Obrigado')">Clique em mim</button>
Sequências de escape em literais de string
O caractere de barra invertida (\ ) tem um propósito especial em strings JavaScript. Combinado com o caractere que o segue, ele representa um caractere que não pode ser representado de outra forma na string. Por exemplo, \n é uma sequência de escape que representa um caractere de nova linha.
Outro exemplo, mencionado anteriormente, é o escape \ ', que representa o caractere de aspas simples (ou apóstrofo). Essa sequência de escape é útil quando você precisa incluir um apóstrofo em um literal de string contido entre aspas simples. Você pode ver porque elas são chamadas de sequências de escape: a barra invertida permite que você escape da interpretação usual do caractere de aspas simples. Em vez de usá-lo para marcar o final da string, você o usa como um apóstrofo:
'You\'re right, it can\'t be a quote'
Três sequências de escape são genéricas e podem ser usadas para representar qualquer caractere, especificando seu código de caractere Unicode como um número hexadecimal. Por exemplo, a sequência \xA9 representa o símbolo de copyright, que tem a codificação Unicode fornecida pelo número hexadecimal A9. Da mesma forma, o escape \u representa um caractere Unicode arbitrário especificado por quatro dígitos hexadecimais ou de um a cinco dígitos quando os dígitos estão entre chaves: \u03c0 representa o caractere π, por exemplo, e \u{1f600} representa o "sorriso cara ”emoji.
Sequências de escape de JavaScript
Sequências | Caractere representado |
---|---|
\0 | O caractere NULL (\u0000) |
\b | Backspace (\u0008) |
\t | Guia horizontal (\u0009) |
\n | Nova linha (\u000A) |
\v | Guia vertical (\u000B) |
\f | Feed de formulário (\u000C) |
\r | Retorno de carro (\u000D) |
\" | Aspas duplas (\u0022) |
\' | Apóstrofo ou aspas simples (\u0027) |
\ \ | Barra invertida (\u005C) |
\xnn | O caractere Unicode especificado pelos dois dígitos hexadecimais nn |
\unnnn | O caractere Unicode especificado pelos quatro dígitos hexadecimais nnnn |
\u{n} | O caractere Unicode especificado pelo ponto de código n, onde n é de um a seis dígitos hexadecimais entre 0 e 10FFFF (ES6) |
Se o caractere \ preceder qualquer caractere diferente dos mostrados na Tabela acima, a barra invertida será simplesmente ignorada (embora versões futuras do idioma possam, é claro, definir novas sequências de escape). Por exemplo, \ # é o mesmo que #. Finalmente, conforme observado anteriormente, o ES5 permite uma barra invertida antes de uma quebra de linha para quebrar um literal de string em várias linhas.
Trabalhando com Strings
Um dos recursos integrados do JavaScript é a capacidade de concatenar strings. Se você usar o operador + com números, ele os adicionará. Mas se você usar esse operador em strings, ele os unirá anexando o segundo ao primeiro. Por exemplo:
let msg = 'Hello, ' + 'world'; // Cria a string
'Hello, world'
let greeting = 'Welcome to my blog,' + ' ' + name;
As strings podem ser comparadas com os operadores padrão === igualdade e !== desigualdade: duas strings são iguais se e somente se consistirem exatamente na mesma sequência de valores de 16 bits. As strings também podem ser comparadas com os operadores <, <=, > e >=. A comparação de strings é feita simplesmente comparando os valores de 16 bits.
Para determinar o comprimento de uma string - o número de valores de 16 bits que ela contém - use a propriedade length da string:
s.length
Além dessa propriedade de comprimento, O JavaScript fornece uma API rica para trabalhar com strings:
let s = 'Hello, world'; // Comece com algum texto.
// Obtendo porções de uma string
s.substring(1,4) // => 'ell': o 2º, 3º e 4º caracteres.
s.slice(1,4) // => 'ell': mesma coisa
s.slice(-3) // => 'rld': últimos 3 caracteres
s.split(', ') // => ['Hello', 'world']: dividir na string delimitadora
// Procurando uma string
s.indexOf('l') // => 2: posição da primeira letra l
s.indexOf('l', 3) // => 3: posição do primeiro 'l' em ou após 3
s.indexOf('zz') // => -1: s não inclui a substring 'zz'
s.lastIndexOf('l') // => 10: posição da última letra l
// Funções de pesquisa booleana no ES6 e posterior
s.startsWith('Hell') // => true: A string começa com este?
s.endsWith('!') // => false: s não termina com isso?
s.includes('or') // => true: s inclui substring 'or'
// Criação de versões modificadas de uma string
s.replace('llo', 'ya') // => 'Heya, world'
s.toLowerCase() // => 'hello, world'
s.toUpperCase() // => 'HELLO, WORLD'
s.normalize() // Normalização Unicode NFC: ES6
s.normalize('NFD') // Normalização NFD. Também 'NFKC', 'NFKD'
// Inspecionando caracteres individuais (16 bits) de uma string
s.charAt(0) // => 'H': o primeiro caractere
s.charAt(s.length-1) // => 'd': o último character
s.charCodeAt(0) // => 72: Número de 16 bits na posição especificada
s.codePointAt(0) // => 72: ES6, funciona para pontos de código > 16 bits
// Funções de preenchimento de uma string no ES2017
'x'.padStart(3) // => ' x': adiciona espaços à esquerda para um comprimento de 3
'x'.padEnd(3) // => 'x ': adicione espaços à direita para um comprimento de 3
'x'.padStart(3, '*') // => '***x': adicione asteriscos à esquerda com comprimento de 3
'x'.padEnd(3, '-') // => 'x---': adicione travessões à direita para um comprimento de 3
// Funções de corte de espaço. trim() é ES5; outros ES2019
' test '.trim() // => 'test': remove os espaços no início e no final
' test '.trimStart() // => 'test ': remove os espaços à esquerda. Também trimLeft
' test '.trimEnd() // => ' test': remove os espaços à direita. Também trimRight
// Métodos de string diversos
s.concat('!') // => 'Hello, world!': apenas use o operador + em vez
'<>'.repeat(5) // => '<><><><><>': concatena n cópias. ES6
Lembre-se de que as strings são imutáveis em JavaScript. Métodos como replace() e toUpperCase() retornam novas strings: eles não modificam a string na qual são chamados.
Strings também podem ser tratados como arrays somente leitura, e você pode acessar caracteres individuais (valores de 16 bits) de uma string usando colchetes em vez do método charAt():
let s = 'hello, world';
s[0] // => "h"
s[s.length-1] // => "d"
Template Literals
No ES6 e posterior, os literais de string podem ser delimitados com crases:
let s = `hello world`;
Isso é mais do que apenas outra sintaxe literal de string, porque esses literais de modelo podem incluir expressões JavaScript arbitrárias. O valor final de um literal de string em crases é calculado avaliando quaisquer expressões incluídas, convertendo os valores dessas expressões em strings e combinando essas strings computadas com os caracteres literais nos crases:
let name = 'Bill';
let greeting = `Hello ${ name }.`; // greeting == 'Hello Bill.'
Tudo entre o ${e o correspondente} é interpretado como uma expressão JavaScript. Tudo fora das chaves é texto literal de string normal. A expressão dentro das chaves é avaliada e então convertida em uma string e inserida no modelo, substituindo o cifrão, as chaves e tudo o que está entre eles.
Um literal de modelo pode incluir qualquer número de expressões. Ele pode usar qualquer um dos caracteres de escape que as strings normais podem, e pode se estender por qualquer número de linhas, sem necessidade de escape especial. O modelo de literal a seguir inclui quatro expressões JavaScript, uma sequência de escape Unicode e pelo menos quatro novas linhas (os valores da expressão também podem incluir novas linhas):
let errorMessage = `\
\u2718 Test failure at ${filename}:${linenumber}:
${exception.message}
Stack trace:
${exception.stack}
`;
A barra invertida no final da primeira linha aqui escapa da nova linha inicial para que a string resultante comece com o caractere Unicode ✘ (\u2718) em vez de uma nova linha.
LITERAIS DE MODELO MARCADOS
Um recurso poderoso, mas menos usado dos literais de modelo, é que, se um nome de função (ou “tag”) vier logo antes da crase de abertura, o texto e os valores das expressões dentro do literal de modelo são passados para a função. O valor deste “literal de modelo marcado” é o valor de retorno da função. Isso pode ser usado, por exemplo, para aplicar escape HTML ou SQL aos valores antes de substituí-los no texto.
ES6 tem uma função de tag embutida: String.raw(). Retorna o texto dentro de crases sem qualquer processamento de escapes de barra invertida:
`\n`.length // => 1: a string tem um único
newline character
String.raw`\n`.length // => 2: um caractere de barra invertida e a letra n
Observe que, embora a parte da tag de um literal de modelo com tag seja uma função, não há parênteses usados em sua invocação. Neste caso muito específico, os caracteres de crase substituem os parênteses de abertura e fechamento.
A capacidade de definir suas próprias funções de tag de modelo é um recurso poderoso do JavaScript. Essas funções não precisam retornar strings e podem ser usadas como construtores, como se definissem uma nova sintaxe literal para a linguagem.
Correspondência de padrões
O JavaScript define um tipo de dados conhecido como expressão regular (ou RegExp) para descrever e combinar padrões em strings de texto. RegExps não são um dos tipos de dados fundamentais em JavaScript, mas têm uma sintaxe literal como os números e as strings, por isso às vezes parecem ser fundamentais. A gramática de literais de expressão regular é complexa e a API que eles definem não é trivial. Como RegExps são poderosos e comumente usados para processamento de texto, esta seção fornece uma breve visão geral.
O texto entre um par de barras constitui um literal de expressão regular. A segunda barra do par também pode ser seguida por uma ou mais letras, que modificam o significado do padrão. Por exemplo:
/^HTML/; // Combina as letras H T M L no início de uma string
/[1-9][0-9]*/; // Corresponde a um dígito diferente de zero, seguido por qualquer número de dígitos
/\bjavascript\b/i; // Corresponde a "javascript" como uma palavra, não diferencia maiúsculas de minúsculas
Os objetos RegExp definem vários métodos úteis e as strings também têm métodos que aceitam argumentos RegExp. Por exemplo:
let text = "testing: 1, 2, 3"; // Texto de amostra
let pattern = /\d+/g; // Corresponde a todas as instâncias de um ou mais dígitos
pattern.test(text) // => true: existe uma correspondência
text.search(pattern) // => 9: posição da primeira correspondência
text.match(pattern) // => ["1", "2", "3"]: matriz de todas as correspondências
text.replace(pattern, "#") // => "testing: #, #, #"
text.split(/\D+/) // => ["","1","2","3"]: dividir em não dígitos