Vorremo rendere disponibile questo progetto open-source per persone in tutto il mondo.

Aiutaci a tradurre il contenuto di questo tutorial nella tua lingua!

In JavaScript, i dati di tipo testuale vengono memorizzati in stringhe. Non esiste un tipo separato per i caratteri singoli.

Il formato utilizzato per le stringhe è sempre UTF-16, non viene influenzato dalla codifica della pagina.

Apici

Ricapitoliamo i tipi di apice.

Le stringhe possono essere racchiuse tra singoli apici, doppi apici o backticks:

let single = 'single-quoted';
let double = "double-quoted";

let backticks = `backticks`;

Gli apici singoli e doppi sono essenzialmente uguali. I backticks, invece, ci consentono di includere una qualsiasi espressione all’interno della stringa, inserendola all’interno di ${…}:

function sum(a, b) {
  return a + b;
}

alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.

Un altro vantaggio nell’utilizzo di backticks è che consentono di dividere la stringa in più righe:

let guestList = `Guests:
 * John
 * Pete
 * Mary
`;

alert(guestList); // una lista di guest, in piu righe

Se proviamo a utilizzare gli apici singoli o doppi allo stesso modo, otterremo un errore:

let guestList = "Guests: // Error: Unexpected token ILLEGAL
  * John";

Gli apici singoli e doppi sono nati insieme al linguaggio, quando non era stato ancora messo in conto la possibilità di stringhe multilinea. Le backticks sono apparse più tardi, per questo risultano più versatili.

Le backticks ci consentono anche di specificare un “template di funzione” prima della backtick di apertura. La sintassi è: func`string`. La funzione func viene chiamata automaticamente, gli viene passata la “string”, può essere cosi trattata dalla funzione. Potete approfondire leggendo la documentazione. Questo viene chiamata “funzione template”. Con questa caratteristica diventa più facile raccogliere stringhe da passare a funzioni, ma è raramente utilizzata.

Caratteri speciali

E’ comunque possibile creare stringhe multilinea con singoli apici utilizzando il “carattere nuova riga”, cioè \n, che significa appunto nuova riga:

let guestList = "Guests:\n * John\n * Pete\n * Mary";

alert(guestList); // una lista di guest multi riga

Ad esempio, queste due funzioni portano allo stesso risultato:

let str1 = "Hello\nWorld"; // due righe utilizzando il "carattere nuova riga"

// due righe utilizzando le backticks
let str2 = `Hello
World`;

Ci sono altri caratteri “speciali” meno comuni. Qui una lista:

Carattere Descrizione
\n Nuova linea
\r Ritorno a capo: non utilizzato da solo. I file di testo Windows utilizzano una combinazione di due caratteri \n\r per rappresentare il termine della riga.
\', \" Apici
\\ Backslash
\t Tab
\b, \f,\v Backspace, Form Feed, Vertical Tab – mantenuti per retrocompatibilità, oggi non sono utilizzati.
\xXX Carattere Unicode rappresentato dal codice esadecimale XX, esempio '\x7A' equivale a 'z'.
\uXXXX Simbolo unicode rappresentato da codice esadecimale XXXX in codifica UTF-16, ad esempio \u00A9 – equivale a ©.
\u{X…XXXXXX} (da 1 a 6 caratteri esadecimali) Un simbolo Unicode in codifica UTF-32. Alcuni caratteri vengono codificati da due simboli unicode, ovvero 4 byte.

Esempi di unicode:

alert( "\u00A9" ); // ©
alert( "\u{20331}" ); // 佫, un raro geroglifico cinese (long unicode)
alert( "\u{1F60D}" ); // 😍, un simbolo di faccia sorridente (long unicode)

Tutti i caratteri speciali iniziano con un backslash \. Che viene anche chiamato “carattere di escape”.

Dobbiamo utilizzarlo anche se abbiamo intenzione di inserire un apice all’interno della stringa.

Ad esempio:

alert( 'I\'m the Walrus!' ); // I'm the Walrus!

Avete visto che abbiamo inserito un backslash \' prima dell’apice interno, altrimenti questo avrebbe indicato la fine della stringa.

Ovviamente, questo è valido per un apice uguale a quello utilizzato in apertura. Quindi, possiamo optare per una soluzione più elegante, ad esempio i doppi apici o i backticks:

alert( `I'm the Walrus!` ); // I'm the Walrus!

Da notare che il backslash \ ha l’unico scopo di aiutare JavaScript nella lettura della stringa, questo verrà poi rimosso. La stringa in memoria non avrà \. Lo avrete sicuramente notato con gli alert dei vari esempi sopra.

Ma se volessimo realmente mostrare un backslash \ dentro la stringa?

E’ possibile farlo, ma dobbiamo esplicitarlo con un doppio backslash \\:

alert( `The backslash: \\` ); // The backslash: \

String length

La proprietà length (lunghezza) contiene la lunghezza della stringa:

alert( `My\n`.length ); // 3

Da notare che \n è contato come unico carattere “speciale”, quindi la lunghezza risulta essere 3.

length è una proprietà

Alcune persone abituate ad altri linguaggi possono confondere al chiamata str.length() con str.length. Questo è un errore.

Infatti str.length è una proprietà numerica, non una funzione. Non c’è alcun bisogno delle parentesi.

Accesso ai caratteri

Per ottenere un carattere alla posizione pos, si utilizzano le parentesi quadre [pos] oppure la chiamata al metodo str.charAt(pos). Il primo carattere parte dalla posizione zero:

let str = `Hello`;

// il primo carattere
alert( str[0] ); // H
alert( str.charAt(0) ); // H

// l'ultimo carattere
alert( str[str.length - 1] ); // o

L’utilizzo delle parentesi quadre è il modo più classico per accedere ad un carattere, mentre charAt esiste principalmente per ragioni storiche.

L’unica differenza sta nel comportamento in casi di carattere non trovato, [] ritorna undefined, e charAt ritorna una stringa vuota:

let str = `Hello`;

alert( str[1000] ); // undefined
alert( str.charAt(1000) ); // '' (una stringa vuota)

Possiamo iterare sui caratteri utilizzando for..of:

for (let char of "Hello") {
  alert(char); // H,e,l,l,o (char diventa "H", poi "e", poi "l" etc)
}

Le stringhe sono immutabili

Le stringhe in JavaScript non possono essere modificate. Risulta impossibile cambiare anche un solo carattere.

Possiamo anche provare a modificarla per vedere che non funziona:

let str = 'Hi';

str[0] = 'h'; // errore
alert( str[0] ); // non funziona

Il metodo utilizzato per aggirare questo problema è creare una nuova stringa ed assegnarla a str sostituendo quella vecchia.

Ad esemepio:

let str = 'Hi';

str = 'h' + str[1];  // rimpiazza str

alert( str ); // hi

Nelle prossime sezioni vedremo ulteriori esempi.

Cambiare il timbro delle lettere

I metodi come toLowerCase() e toUpperCase() cambiano il timbro delle lettere:

alert( 'Interface'.toUpperCase() ); // INTERFACE
alert( 'Interface'.toLowerCase() ); // interface

Altrimenti, possiamo agire anche su un singolo carattere:

alert( 'Interface'[0].toLowerCase() ); // 'i'

Cercare una sotto-stringa

Ci sono diversi modi per cercare una sotto-stringa all’interno di una stringa.

str.indexOf

Il primo metodo è str.indexOf(substr, pos).

Quello che fa è cercare substr in str, ad iniziare dalla posizione pos, e ne ritorna la posizione una volta trovata, se non trova corrispondenze ritorna -1.

Ad esempio:

let str = 'Widget with id';

alert( str.indexOf('Widget') ); // 0, perché 'Widget' è stato trovato all'inizio
alert( str.indexOf('widget') ); // -1, non trovato, la ricerca è case-sensitive

alert( str.indexOf("id") ); // 1, "id" è stato trovato alla posizione di indice 1

Il secondo parametro opzionale ci consente di cercare a partire dalla posizione fornita.

Ad esempio, la prima occorrenza di "id" è alla posizione 1. Per trovare la successiva occorrenza, dovremmo iniziare a cercare dalla posizione 2:

let str = 'Widget with id';

alert( str.indexOf('id', 2) ) // 12

Se siamo interessati a tutte le occorrenze, possiamo utilizzare indexOf in un ciclo. Ogni chiamata viene fatta a partire dalla posizione della precedente corrispondenza:

let str = 'As sly as a fox, as strong as an ox';

let target = 'as'; // procediamo con la ricerca

let pos = 0;
while (true) {
  let foundPos = str.indexOf(target, pos);
  if (foundPos == -1) break;

  alert( `Found at ${foundPos}` );
  pos = foundPos + 1; // continua la ricerca a partire dalla prossima posizione
}

Lo stesso algoritmo può essere riscritto più brevemente:

let str = "As sly as a fox, as strong as an ox";
let target = "as";

let pos = -1;
while ((pos = str.indexOf(target, pos + 1)) != -1) {
  alert( pos );
}
str.lastIndexOf(substr, position)

Un altro metodo simile è str.lastIndexOf(substr, position), che effettua la ricerca partendo dalla fine della stringa.

Elenca quindi le occorrenze in ordine inverso.

C’è solo un piccolo inconveniente dovuto all’utilizzo di indexOf all’interno delle espressioni if. Non possiamo inserirlo in un if in questo modo:

let str = "Widget with id";

if (str.indexOf("Widget")) {
    alert("We found it"); // non funziona!
}

L’ alert nell’esempio sopra non viene mostrato perché str.indexOf("Widget") ritorna 0 (significa che è stata trovata una corrispondenza nella posizione iniziale). Ed è corretto, ma if considera 0 come false.

Quindi dovremmo verificare il -1, in questo modo:

let str = "Widget with id";

if (str.indexOf("Widget") != -1) {
    alert("We found it"); // ora funziona!
}

Il trucco del NOT bit a bit

Uno dei trucchi più utilizzati è l’operatore di