Le stringhe JavaScript sono immutabili? Ho bisogno di un “costruttore di stringhe” in JavaScript?

Javascript usa stringhe immutabili o mutabili? Ho bisogno di un “costruttore di stringhe”?

Sono immutabili. Non è ansible modificare un carattere all’interno di una stringa con qualcosa come var myString = "abbdef"; myString[2] = 'c' var myString = "abbdef"; myString[2] = 'c' . I metodi di manipolazione delle stringhe come trim , slice restituiscono nuove stringhe.

Tuttavia, ho sempre sentito quello che Ash ha menzionato nella sua risposta (che usando Array.join è più veloce per la concatenazione) quindi ho voluto testare i diversi metodi di concatenazione delle stringhe e l’astrazione del modo più veloce in StringBuilder. Ho scritto alcuni test per vedere se questo è vero (non lo è!).

Questo era quello che credevo sarebbe stato il modo più veloce, anche se continuavo a pensare che l’aggiunta di una chiamata al metodo potrebbe renderla più lenta …

 function StringBuilder() { this._array = []; this._index = 0; } StringBuilder.prototype.append = function (str) { this._array[this._index] = str; this._index++; } StringBuilder.prototype.toString = function () { return this._array.join(''); } 

Ecco i test di velocità delle prestazioni. Tutti e tre creano una gigantesca stringa composta da concatenare "Hello diggity dog" centomila volte in una stringa vuota.

Ho creato tre tipi di test

  • Utilizzando Array.push e Array.join
  • Utilizzare l’indicizzazione di array per evitare Array.push , quindi utilizzare Array.join
  • Concatenazione di stringhe diritte

Poi ho creato gli stessi tre test StringBuilderConcat in StringBuilderConcat , StringBuilderArrayPush e StringBuilderArrayIndex http://jsperf.com/string-concat-without-sringbuilder/5 Andate lì ed eseguite i test in modo da ottenere un buon esempio. Nota che ho corretto un piccolo bug, quindi i dati per i test sono stati cancellati, aggiornerò la tabella una volta che ci saranno abbastanza dati sulle prestazioni. Vai a http://jsperf.com/string-concat-without-sringbuilder/5 per la vecchia tabella dati.

Ecco alcuni numeri dal 21 febbraio 2013, se non vuoi seguire il link. Il numero su ciascun test è in operazioni / secondo ( più alto è meglio )

 | Browser | Index | Push | Concat | SBIndex | SBPush | SBConcat | --------------------------------------------------------------------------- | Chrome 24.0.1312 | 83 | 87 | 702 | 69 | 87 | 165 | | Chrome 25.0.1364 | 43 | 47 | 620 | 42 | 42 | 68 | | Firefox 10.0.10 | 164 | 164 | 533 | 164 | 16 | 421 | | Firefox 19.0 | 70 | 70 | 259 | 70 | 70 | 186 | | Exploder 7.0 | 51 | 33 | 58 | 31 | 37 | 45 | | Exploder 8.0 | 48 | 30 | 58 | 30 | 36 | 36 | | Exploder 9.0 | 87 | 64 | 95 | 61 | 61 | 61 | | Opera 12.14 | 125 | 154 | 66 | 106 | 137 | 63 | 

I risultati

  • Oggigiorno, tutti i browser gestiscono bene la concatenazione delle stringhe. Array.join aiuta solo Opera

  • Complessivamente, Chrome è il più veloce, con un clock di 1025 operazioni al secondo in 27.0. 10 volte più veloce rispetto all’utilizzo di Array.join ()

  • Firefox è al secondo posto a circa 550 ops / sec (ma il 20.0 sembra essersi regredito). Array.join è circa 4-5 volte più lento.

  • IE è il più veloce con concatenazione di stringhe diritte, è molto lento usando Array.join e Array.push . IE 9 rende Array.join non così lento e tutte le astrazioni SB funzionano quasi allo stesso modo (probabilmente a causa del sovraccarico del metodo)

  • Opera è l’unico in cui l’ Array.join aiuta effettivamente, è 2-3 volte più veloce della concatenazione di stringhe.

  • Creare un object StringBuilder per astrarre i problemi di prestazioni di ogni browser fa più male che bene. Il sovraccarico delle chiamate al metodo può essere accettabile, ma la tendenza sembra essere che i browser gestiscano la concatenazione di stringhe in modo più intelligente. Avrebbe senso solo se il tuo pubblico di destinazione è Opera, quindi puoi usare Array.join lì e usare la concatenazione di String ovunque (questo significa che tutti gli altri browser stanno prendendo un colpo)

Spero che qualcun altro lo trovi utile

Diverso test case

Dal momento che @RoyTinker pensava che il mio test fosse difettoso, ho creato un nuovo caso che non crea una grande stringa concatenando la stessa stringa, ma usa un carattere diverso per ogni iterazione. La concatenazione delle stringhe sembrava ancora più veloce o altrettanto veloce. Facciamo funzionare quei test.

Suggerisco a tutti di continuare a pensare ad altri modi per testarlo, grazie per l’input Roy.

http://jsperf.com/string-concat-without-sringbuilder/7

dal libro del rinoceronte :

In JavaScript, le stringhe sono oggetti immutabili, il che significa che i caratteri al loro interno non possono essere modificati e che qualsiasi operazione sulle stringhe crea effettivamente nuove stringhe. Le stringhe sono assegnate per riferimento, non per valore. In generale, quando un object viene assegnato per riferimento, una modifica apportata all’object attraverso un riferimento sarà visibile attraverso tutti gli altri riferimenti all’object. Poiché le stringhe non possono essere modificate, tuttavia, puoi avere più riferimenti a un object stringa e non preoccuparti che il valore della stringa cambierà senza che tu lo sappia

Suggerimento sulle prestazioni:

Se devi concatenare stringhe di grandi dimensioni, inserisci le parti di una stringa in un array e utilizza il metodo Array.Join() per ottenere la stringa generale. Questo può essere molte volte più veloce per concatenare un gran numero di stringhe.

Non c’è StringBuilder in JavaScript.

Le stringhe JavaScript sono davvero immutabili.

Il valore del tipo di stringa è immutabile, ma l’object String, che viene creato utilizzando il costruttore String (), è modificabile, poiché è un object ed è ansible aggiungervi nuove proprietà.

 > var str = new String("test") undefined > str [String: 'test'] > str.newProp = "some value" 'some value' > str { [String: 'test'] newProp: 'some value' } 

Nel frattempo, sebbene sia ansible aggiungere nuove proprietà, non è ansible modificare le proprietà già esistenti

Uno screenshot di un test nella console di Chrome

In conclusione, 1. tutto il valore del tipo di stringa (tipo primitivo) è immutabile. 2. L’object String è mutabile, ma il valore del tipo di stringa (tipo primitivo) che contiene è immutabile.

Le stringhe in Javascript sono immutabili

Per quanto riguarda la tua domanda (nel tuo commento alla risposta di Ash) sullo StringBuilder in ASP.NET Ajax gli esperti sembrano non essere d’accordo su questo.

Christian Wenz dice nel suo libro Programmazione ASP.NET AJAX (O’Reilly) che “questo approccio non ha alcun effetto misurabile sulla memoria (infatti, l’implementazione sembra essere più veloce rispetto all’approccio standard).”

D’altra parte Gallo e altri nel loro libro ASP.NET AJAX in Action (Manning) dicono che “Quando il numero di stringhe da concatenare è maggiore, il generatore di stringhe diventa un object essenziale per evitare enormi cali di prestazioni”.

Suppongo che tu abbia bisogno di fare il tuo benchmarking e che i risultati potrebbero differire anche tra i browser. Tuttavia, anche se non migliora le prestazioni, potrebbe comunque essere considerato “utile” per i programmatori che sono abituati a codificare con StringBuilder in linguaggi come C # o Java.

Le stringhe sono immutabili : non possono cambiare, possiamo sempre creare nuove stringhe.

Esempio:

 var str= "Immutable value"; // it is immutable var other= statement.slice(2, 10); // new string 

È un post in ritardo, ma non ho trovato un buon preventivo tra le risposte.

Ecco un punto a parte tranne da un libro affidabile:

Le stringhe sono immutabili in ECMAScript, il che significa che una volta creati, i loro valori non possono cambiare. Per cambiare la stringa detenuta da una variabile, la stringa originale deve essere distrutta e la variabile riempita con un’altra stringa contenente un nuovo valore … -Professional JavaScript per gli sviluppatori Web, 3 ° ed., P.43

Ora, la risposta che cita l’estratto del libro di Rhino ha ragione sull’immutabilità della stringa, ma sta dicendo erroneamente che “le stringhe sono assegnate per riferimento, non per valore”. (probabilmente originariamente intendevano mettere le parole in modo opposto).

L’idea errata di “riferimento / valore” è chiarita nel “JavaScript professionale”, capitolo denominato “Valori primitivi e di riferimento”:

I cinque tipi primitivi … [sono]: Undefined, Null, Boolean, Number e String. Si dice che queste variabili siano accessibili per valore, perché si sta manipolando il valore effettivo memorizzato nella variabile. -Professionale JavaScript per gli sviluppatori Web, 3rd Ed., P.85

è contrario agli oggetti :

Quando si manipola un object, si sta veramente lavorando a un riferimento a quell’object piuttosto che all’object stesso. Per questo motivo, si dice che tali valori siano accessibili per riferimento. -Professionale JavaScript per gli sviluppatori Web, 3rd Ed., P.85