Skip to content

6. As cadeias de caracteres

As cadeias de caracteres do JavaScript são muito semelhantes às do PHP.

Image

6.1. script [str-01]

A primeira coisa a entender é que, uma vez criada, uma string não pode mais ser modificada. Existem vários métodos para gerar uma nova string a partir da string inicial, mas esta permanece sempre inalterada. Além disso, uma string de caracteres pode ser de dois tipos:

  • [string] quando inicializada com uma string literal;
  • [object] quando é criada como instância da classe [String];

''use strict';

// as cadeias de caracteres são somente de leitura (não podem ser modificadas)

// uma sequência de caracteres
const chaîne1 = "abcd ";
// tipo
console.log("typeof(chaîne1)=", typeof (chaîne1));
// caractere nº 2
console.log("chaîne1[2]=", chaîne1[2]);
// gera um erro
chaîne1[2] = "0";

Execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Temp\19-09-01\javascript\strings\str-01.js"
typeof(chaîne1)= string
chaîne1[2]= c
c:\Temp\19-09-01\javascript\strings\str-01.js:1
TypeError: Cannot assign to read only property '2' of string 'abcd '
at Object.<anonymous> (c:\Temp\19-09-01\javascript\strings\str-01.js:12:12)
at Generator.next (<anonymous>)

6.2. script [str-02]

Este script mostra que é possível construir uma sequência de caracteres de duas maneiras.


''use strict';

// as cadeias de caracteres podem ser de dois tipos

// uma cadeia literal
const chaîne1 = "abcd ";
// tipo
console.log("typeof(chaîne1)=", typeof (chaîne1));
// instância de String
const chaîne2 = new String("xyzt");
// tipo
console.log("typeof(chaîne2)=", typeof (chaîne2));
// outra forma de escrita (sem new) – tipo [string] e não [object]
const chaîne3 = String("12 34");
// tipo
console.log("typeof(chaîne3)=", typeof (chaîne3));
// o tipo [string] e o tipo [object] oferecem os mesmos métodos, os da classe String
console.log("chaîne1.length=", chaîne1.length);
console.log("chaîne2.length=", chaîne2.length);

Comentários

  • linha 6: o método usual de definição de uma sequência de caracteres. [chaîne1] será do tipo [string];
  • linha 10: é possível construir uma cadeia de caracteres usando o construtor da classe [String]. [chaîne2] será do tipo [object];

Execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\strings\str-02.js"
typeof(chaîne1)= string
typeof(chaîne2)= object
typeof(chaîne3)= string
chaîne1.length= 5
chaîne2.length= 4

O tipo [string] dispõe dos métodos da classe [String].

6.3. script [str-03]

Este script mostra uma sequência específica com interpolação de variáveis.


'use strict';

// cadeia
const chaîne = "Introduction à Javascript par l'exemple";
// cadeia com interpolação de variáveis
const str = `[${chaîne}].substr(3, 2)=` + chaîne.substr(3, 2)
console.log(str);

Comentários

  • linha 6: é possível ter cadeias de caracteres contendo expressões ${variável}, que são substituídas pelo valor da variável. Trata-se da mesma lógica das variáveis $ nas cadeias de caracteres PHP. Observe a notação dessa sequência: ela é delimitada por “backstick” ou apóstrofo invertido (AltGr-7 em um teclado francês);

Execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Temp\19-09-01\javascript\strings\tempCodeRunnerFile.js"
[Introduction à Javascript par l'exemple].substr(3, 2)=ro

6.4. script [str-04]

A string com interpolação de variáveis continua sendo insuficiente. De fato, não é possível substituir a variável pela expressão na forma ${variável}. Para quem já programou em C, não há nada como as funções [printf, sprintf] para escrever ou construir strings formatadas. Centenas de desenvolvedores criaram milhares de pacotes JavaScript, formando um ecossistema imenso. Quando surge uma necessidade que não é atendida nativamente pelo JavaScript, é hora de procurar um pacote que a satisfaça. Para isso, utilizamos o gerenciador de pacotes [npm]. Ele possui uma opção [search] que permite procurar uma sequência de caracteres na descrição dos pacotes. [npm] retorna a lista de pacotes que atendem à pesquisa. Portanto, vamos procurar a sequência [sprintf] na descrição dos pacotes:

Image

  • na coluna [4], as palavras-chave dos pacotes da coluna [3];
  • na coluna [5], a descrição dos pacotes da coluna [3];

O próximo passo é acessar o site da ferramenta [npm], [https://www.npmjs.com/] e ler a descrição dos pacotes:

Image

No [3], examinamos a lista de pacotes e escolhemos um.

Image

Na descrição do pacote, encontram-se as informações para instalá-lo e utilizá-lo:

Image

Instalamos o pacote [sprintf-js] em um terminal do [VSCode]:

Image

Essa instalação modificará o arquivo [package.json] localizado na raiz da pasta [javascript] [2]:

Image

Vemos acima que o pacote foi instalado nos [dependencies], ou seja, nos pacotes necessários para a execução do projeto. Vale lembrar que os pacotes necessários são colocados em [devDependencies] apenas durante o desenvolvimento do projeto. Eles não são utilizados durante a execução. Essa diferença é importante quando é necessário criar a versão final do projeto para sua entrada em produção. Existem ferramentas para:

  • reunir todos os arquivos jS necessários para a execução em um único arquivo. Os pacotes [devDependencies], portanto, não são incluídos nesse arquivo final;
  • minimizá-lo, ou seja, reduzir seu tamanho ao mínimo possível. Para isso, por exemplo, todos os comentários são removidos;
  • “ofuscar” o código para torná-lo difícilmente compreensível. Por exemplo, as variáveis taxa, salário e imposto serão substituídas pelas variáveis a, b e c;
  • realizar outras otimizações;

Essa otimização do arquivo final de um projeto jS é utilizada na programação web. Um aplicativo web pode depender de um grande número de arquivos JavaScript. O carregamento desses arquivos por um navegador pode retardar a exibição da primeira página do aplicativo. A otimização anterior visa melhorar esse tempo de carregamento. Se o tempo de carregamento for considerado muito longo pelos usuários, a aplicação não será utilizada.

Agora que dispomos do pacote [sprintf-js], precisamos utilizá-lo. Trata-se do script [str-04]:


'use strict';
// uso de um pacote externo para disponibilizar a função sprintf
import { sprintf } from 'sprintf-js';
// cadeia
const chaîne = "Introduction à Javascript par l'exemple";
// método
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

Com o ECMAScript 6, usamos a palavra-chave [import] para importar um objeto exportado por um pacote. Para saber o que o pacote exporta, podemos consultar seu código:

Image

  • no [1], clique com o botão direito do mouse no pacote importado;
  • no [2], queremos ver a definição;
  • em [3-4], vemos que o pacote exporta uma função chamada [sprintf];

A função [sprintf] do pacote [sprintf-js] é importada com a instrução:


import { sprintf } from 'sprintf-js';

O código completo:


'use strict';
// uso de um pacote externo para disponibilizar a função sprintf
import { sprintf } from 'sprintf-js';
// cadeia
const chaîne = "Introduction à Javascript par l'exemple";
// método
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

produz os seguintes resultados:


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\strings\str-04.js"
c:\Temp\19-09-01\javascript\strings\str-04.js:3
import { sprintf } from 'sprintf-js';
^

SyntaxError: Unexpected token {
at new Script (vm.js:79:7)
at createScript (vm.js:251:10)
at Object.runInThisContext (vm.js:303:10)
at Module._compile (internal/modules/cjs/loader.js:657:28)

Na linha 3, a instrução [import] não foi compreendida. Isso se deve ao fato de que a versão 10.15.1 do [node.js] utilizada neste curso (setembro de 2019) ainda não segue a norma ECMAScript para a importação de pacotes chamados módulos. Em 2019, o [node.js] segue um padrão de módulos denominado CommonJS. A integração dos módulos ECMAScript pelo [node.js] está prevista para 2020. Mais uma vez, os desenvolvedores se empenharam e criaram pacotes que permitem o uso dos módulos ES6 com o [node.js] já a partir de agora (2019).

Vamos utilizar um pacote chamado [esm] (Módulos ECMAScript). Vamos instalá-lo em um terminal do projeto [javascript]:

Image

No [4], percebemos que a instalação do pacote [esm] [1-3] alterou o arquivo [javascript/package.json].

Ainda não terminamos. Para que o módulo [esm] seja utilizado pelo [node.js], é necessário executá-lo com o argumento [-r esm].

Portanto, alteramos a configuração da extensão [Code Runner] do [VSCode]:

Image

Image

No [11], adicionamos o argumento [-r esm] e salvamos (Ctrl-S) a configuração.

Agora, podemos executar o script [str-04]:


'use strict';
// uso de um pacote externo para disponibilizar a função sprintf
import { sprintf } from 'sprintf-js';
// cadeia
const chaîne = "Introduction à Javascript par l'exemple";
// método substr
console.log(sprintf("[%s].substr(3,2)=[%s]", chaîne, chaîne.substr(3, 2)));

Image

6.5. script [str-05]

Veja o que diz a documentação sobre a função [sprintf]:

Os placeholders na string de formato são marcados por % e são seguidos por um ou mais desses elementos, nesta ordem:

  • Um número opcional seguido pelo sinal $, que seleciona qual índice de argumento deve ser usado para o valor. Se não for especificado, os argumentos serão colocados na mesma ordem que os placeholders na string de entrada.
  • Um sinal de mais (+) opcional que força a precedência do resultado com um sinal de mais ou de menos em valores numéricos. Por padrão, apenas o sinal de menos (-) é usado em números negativos.
  • Um especificador de preenchimento opcional que indica qual caractere usar para preenchimento (se especificado). Os valores possíveis são 0 ou qualquer outro caractere precedido por uma ' (aspas simples). O padrão é preencher com espaços.
  • Um sinal de menos (-) opcional, que faz com que o sprintf alinhe à esquerda o resultado desse marcador de posição. O padrão é alinhar o resultado à direita.
  • Um número opcional que indica quantos caracteres o resultado deve ter. Se o valor a ser retornado for menor que esse número, o resultado será preenchido. Quando usado com o especificador de tipo j (JSON), o comprimento do preenchimento especifica o tamanho da tabulação usada para recuo.
  • Um modificador de precisão opcional, composto por um . (ponto) seguido por um número, que indica quantos dígitos devem ser exibidos para números de ponto flutuante. Quando usado com o especificador de tipo g, ele especifica o número de dígitos significativos. Quando usado em uma string, faz com que o resultado seja truncado.
  • Um especificador de tipo que pode ser qualquer um dos seguintes:
    • % — retorna o caractere % literal
    • b — retorna um inteiro como número binário
    • c — retorna um inteiro como o caractere com esse valor
    • d ou i — retorna um inteiro como um número decimal com sinal
    • e — retorna um número de precisão flutuante na notação científica
    • u — retorna um inteiro como um número decimal sem sinal
    • f — retorna um valor float tal como está; consulte as notas sobre precisão acima
    • g — retorna um float tal como está; consulte as notas sobre precisão acima
    • o — retorna um inteiro como número octal
    • s — retorna uma string tal como está
    • t — retorna verdadeiro ou falso
    • T — retorna o tipo do argumento1
    • v — retorna o valor primitivo do argumento especificado
    • x — retorna um inteiro como número hexadecimal (letras minúsculas)
    • X — retorna um inteiro como um número hexadecimal (em maiúsculas)
    • j — retorna um objeto ou array JavaScript como uma string codificada em JSON

O script [script-05] implementa alguns desses formatos:


'use strict';
// uso de um pacote externo para disponibilizar a função sprintf
import { sprintf } from 'sprintf-js';
// cadeia
const chaîne = "Javascript";
// cadeias de caracteres
console.log(sprintf("[%s, %%s]=>[%s]", chaîne, chaîne));
console.log(sprintf("[%s, %%20s]=>[%20s]", chaîne, chaîne));
console.log(sprintf("[%s, %%-20s]=>[%-20s]", chaîne, chaîne));
// inteiros
console.log(sprintf("[%d, %%d]=>[%d]", 10, 10));
console.log(sprintf("[%d, %%4d]=>[%4d]", 10, 10));
console.log(sprintf("[%d, %%-4d]=>[%-4d]", 10, 10));
console.log(sprintf("[%d, %%04d]=>[%04d]", 10, 10));
// números reais
console.log(sprintf("[%f, %%f]=>[%f]", -10.5, -10.5));
console.log(sprintf("[%f, %%10.2f]=>[%10.2f]", -10.5, -10.5));
console.log(sprintf("[%f, %%-10.2f]=>[%-10.2f]", -10.5, -10.5));
console.log(sprintf("[%f, %%010.3f]=>[%010.3f]", -10.5, -10.5));
// json
console.log(sprintf("personne (%%j)=%j", { nom: "mathieu", âge: 34 }));
// tipo
console.log(sprintf("type personne (%%T)=%T", { nom: "mathieu", âge: 34 }));
// booleano
console.log(sprintf("booléen (%%t)=%t", 4 === 4));

Execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\strings\str-05.js"
[Javascript, %s]=>[Javascript]
[Javascript, %20s]=>[ Javascript]
[Javascript, %-20s]=>[Javascript ]
[10, %d]=>[10]
[10, %4d]=>[ 10]
[10, %-4d]=>[10 ]
[10, %04d]=>[0010]
[-10.5, %f]=>[-10.5]
[-10.5, %10.2f]=>[ -10.50]
[-10.5, %-10.2f]=>[-10.50 ]
[-10.5, %010.3f]=>[-00010.500]
personne (%j)={"nom":"mathieu","âge":34}
type personne (%T)=object
booléen (%t)=true

6.6. script [str-06]

O script [str-06] apresenta alguns métodos da classe [String] que também podem ser utilizados no tipo [string]:


'use strict';
// uso de um pacote externo para disponibilizar a função sprintf
import { sprintf } from 'sprintf-js';
// cadeia
const chaîne = "  Introduction à Javascript ";
// alguns métodos
// substr(10,2): 2 caracteres a partir do 10º
console.log(sprintf("[%s].substr(10,2)=[%s]", chaîne, chaîne.substr(10, 2)));
// trim: remoção de espaços em branco no início e no final da string (espaço em branco = \b \t \r \n \f)
console.log(sprintf("[%s].trim()=[%s]", chaîne, chaîne.trim()));
// toLowerCase: conversão para letras minúsculas
console.log(sprintf("[%s].toLowerCase=[%s]", chaîne, chaîne.toLowerCase()));
// toUpperCase: conversão para maiúsculas
console.log(sprintf("[%s].toUpperCase=[%s]", chaîne, chaîne.toUpperCase()));
// indexOf: posição de uma subcadei a procurada na cadeia; -1 se a subcadeia não existir
console.log(sprintf("[%s].indexOf('Java')=[%s]", chaîne, chaîne.indexOf('Java')));
console.log(sprintf("[%s].trim().indexOf('abcd')=[%s]", chaîne, chaîne.indexOf('abcd')));
// includes: verdadeiro se a sequência procurada estiver na sequência
console.log(sprintf("[%s].includes('Java')=[%s]", chaîne, chaîne.includes('Java')));
// length: comprimento da string — não é um método, mas uma propriedade
console.log(sprintf("[%s].length=[%s]", chaîne, chaîne.length));
// slice (7,10): sequência dos caracteres do 7º ao 9º
console.log(sprintf("[%s].slice(7,10)=[%s]", chaîne, chaîne.slice(7, 10)));
// match: procura uma expressão na sequência de caracteres — essa expressão pode ser uma expressão regular
// /intro/i: expressão regular que designa a sequência [intro] em maiúsculas ou minúsculas
// retorna a sequência encontrada
console.log(sprintf("[%s].match(/intro/i)=[%s]", chaîne, chaîne.match(/intro/i)));
// substituir: substitui a string1 pela string2 na string
// substitui a primeira ocorrência de i por x
console.log(sprintf("[%s].replace('i','x')=[%s]", chaîne, chaîne.replace('i', 'x')));
// substitui todas as ocorrências de i por x
// /i/g é uma expressão regular que designa todas (g) as ocorrências de i
console.log(sprintf("[%s].replace(/i/g,'x')=[%s]", chaîne, chaîne.replace(/i/g, 'x')));
// split: divide a cadeia em palavras separadas pelo parâmetro de divisão
// retorna a matriz dessas palavras
// /\s*/: palavras separadas por zero ou mais espaços
console.log(sprintf("[%s].split(/\\s*/)=[%s]", chaîne, chaîne.split(/\s*/)));
// /\s+/: palavras separadas por um ou mais espaços
console.log(sprintf("[%s].split(/\\s+/)=[%s]", chaîne, chaîne.split(/\s+/)));

Execução


[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\strings\str-06.js"
[ Introduction à Javascript ].substr(10,2)=[ti]
[ Introduction à Javascript ].trim()=[Introduction à Javascript]
[ Introduction à Javascript ].toLowerCase=[ introduction à javascript ]
[ Introduction à Javascript ].toUpperCase=[ INTRODUCTION À JAVASCRIPT ]
[ Introduction à Javascript ].indexOf('Java')=[17]
[ Introduction à Javascript ].trim().indexOf('abcd')=[-1]
[ Introduction à Javascript ].includes('Java')=[true]
[ Introduction à Javascript ].length=[28]
[ Introduction à Javascript ].slice(7,10)=[duc]
[ Introduction à Javascript ].match(/intro/i)=[Intro]
[ Introduction à Javascript ].replace('i','x')=[ Introductxon à Javascript ]
[ Introduction à Javascript ].replace(/i/g,'x')=[ Introductxon à Javascrxpt ]
[ Introduction à Javascript ].split(/\s*/)=[,I,n,t,r,o,d,u,c,t,i,o,n,à,J,a,v,a,s,c,r,i,p,t,]
[ Introduction à Javascript ].split(/\s+/)=[,Introduction,à,Javascript,]