2012-01-15 15 views
7

Perchéchiamata [] .reverse su una stringa

[].reverse.call("string"); 

fallisce (errore sia in Firefox e IE, restituisce la stringa originale in cromo), mentre chiamando tutti gli altri metodi array su un'opera stringa?

>>> [].splice.call("string",3) 
["i", "n", "g"] 
>>> [].map.call("string",function (a) {return a +a;}) 
["ss", "tt", "rr", "ii", "nn", "gg"] 
+0

_ "tutti gli altri metodi di array" _ - fa '.Sort()' lavoro? Per quelli che funzionano, funzionano in tutti i browser? (Immagino che fallirebbero per i vecchi browser che non hanno implementato la notazione dell'indice '[]' in stile array per le stringhe, sebbene non l'abbia provato.) – nnnnnn

+0

L'ordinamento @nnnnnn non funziona per lo stesso stesso motivo – Hai

+0

@Hai: FYI, '.splice()' non funziona davvero. Chrome è abbastanza gentile da darti il ​​valore restituito, ma se fai riferimento alla stringa originale prima di giuntarla, scoprirai che non è stata modificata. –

risposta

8

Poiché .reverse() modifica un Array e stringhe sono immutabili.


Si potrebbe prendere in prestito Array.prototype.slice per convertire a una matrice, poi invertire e farne parte.

var s = "string"; 

var s2 = [].slice.call(s).reverse().join(''); 

Basta essere consapevoli che nelle vecchie versioni di IE, non si può manipolare una stringa come un array.

+1

Ben fatto - la brevità è l'anima dell'umorismo –

+1

@AdamRackis: Grazie, ma ora sono andato a rovinare il tuo complemento. :) –

+0

@amnotiam, sono troppo tardi, scusa. – OnTheFly

4

Vedere la risposta di @am non sono per il motivo per cui non funziona. Tuttavia, se volete sapere come eseguire questa operazione, convertirlo in un array prima:

"string".split('').reverse().join(''); // "gnirts" 
+0

+1 '.split()' sarà una conversione di array più compatibile con il browser di '[] .slice()'. –

5

La tecnica seguente (o simile) è comunemente usato per invertire una stringa in JavaScript:

// Don’t use this! 
var naiveReverse = function(string) { 
    return string.split('').reverse().join(''); 
} 

In effetti, tutte le risposte postate finora sono una variazione di questo modello. Tuttavia, ci sono alcuni problemi con questa soluzione. Per esempio:

naiveReverse('foo bar'); 
// → 'rab �� oof' 
// Where did the `` symbol go? Whoops! 

Se vi state chiedendo il motivo per cui questo accade, read up on JavaScript’s internal character encoding. (TL; DR:. è un simbolo astrale, e JavaScript espone come due unità di codice separati)

Ma c'è di più:

// To see which symbols are being used here, check: 
// http://mothereff.in/js-escapes#1ma%C3%B1ana%20man%CC%83ana 
naiveReverse('mañana mañana'); 
// → 'anãnam anañam' 
// Wait, so now the tilde is applied to the `a` instead of the `n`? WAT. 

Una buona stringa da testare stringa implementazioni inversa è the following:

'foo bar mañana mañana' 

Perché? Poiché contiene un simbolo astrale () (che sono represented by surrogate pairs in JavaScript) e un simbolo di combinazione (lo nell'ultimo mañana consiste in realtà di due simboli: U + 006E LATIN SMALL LETTER N e U + 0303 COMBINING TILDE).

L'ordine in cui appaiono le coppie sostitutive non può essere invertito, altrimenti il ​​simbolo astrale non verrà più visualizzato nella stringa "invertita". Ecco perché hai visto i segni �� nell'output per l'esempio precedente.

La combinazione di segni viene sempre applicata al simbolo precedente, quindi è necessario considerare sia il simbolo principale (U + 006E LATIN SMALL LETTER N) come il simbolo di combinazione (U + 0303 COMBINING TILDE) nel suo insieme. Invertire il loro ordine farà sì che il segno di combinazione venga abbinato a un altro simbolo nella stringa. Ecco perché l'output di esempio aveva anziché ñ.

Speriamo che questo spieghi perché tutte le risposte postate finora sono errate.


per rispondere alla tua domanda iniziale - come [correttamente] invertire una stringa in JavaScript -, ho scritto una piccola libreria JavaScript che è in grado di Unicode-aware inversione di stringa. Non ha nessuno dei problemi che ho appena menzionato. La libreria si chiama Esrever; il suo codice è su GitHub e funziona praticamente in qualsiasi ambiente JavaScript. Viene fornito con un programma di utilità/binario di shell, quindi è possibile invertire facilmente le stringhe dal terminale se lo si desidera.

var input = 'foo bar mañana mañana'; 
esrever.reverse(input); 
// → 'anañam anañam rab oof'