2012-01-15 45 views
7

爲什麼電話[] .reverse上的繩子

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

失敗(在Firefox的錯誤,即返回鉻原始字符串),同時呼籲在一根繩子上工作的所有其它陣列的方法?

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

_「所有其他數組方法」_「做'.sort()'工作嗎?對於那些能夠工作的人,他們是否適用於所有瀏覽器? (我猜想他們會失敗的舊的瀏覽器沒有實現字符串的數組樣式'[]'索引表示法,雖然我沒有測試它。) – nnnnnn 2012-01-15 00:26:40

+0

@nnnnnn排序不工作爲同樣的原因 – Hai 2012-01-15 00:34:44

+0

@Hai:僅供參考,'.splice()'不起作用。 Chrome非常友好,可以爲您提供返回的值,但如果您在拼接之前引用原始字符串,則會發現它未被修改。 – 2012-01-15 00:36:29

回答

8

因爲.reverse()修改了一個數組,並且字符串是不可變的。您可以借用Array.prototype.slice轉換爲數組,然後反向並加入。

var s = "string"; 

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

請注意,在舊版本的IE中,您不能操縱像Array這樣的字符串。

+1

幹得好 - 簡潔是機智的靈魂 – 2012-01-15 00:22:37

+1

@AdamRackis:謝謝,但現在我已經走了,搞砸了你的補充。 :) – 2012-01-15 00:25:17

+0

@amnotiam,我太晚了,對不起。 – OnTheFly 2012-01-15 04:56:49

4

請參閱@am不,我是爲什麼它不起作用的答案。不過,如果你想知道如何做到這一點,將其轉換爲一個數組第一:

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

+1'.split()'將比'[] .slice()'更適合瀏覽器的數組轉換。 – 2012-01-15 00:26:27

5

下面的技術(或類似)是常用的JavaScript來扭轉一個字符串:

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

事實上,迄今爲止發佈的所有答案都是這種模式的變體。但是,這種解決方案存在一些問題。例如:

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

如果你想知道爲什麼會這樣,read up on JavaScript’s internal character encoding。 (TL; DR:是星體符號,和JavaScript公開它作爲兩個單獨的代碼單位)

但還有更多:

// 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. 

一個好的字符串,以測試串反轉的實現是the following

'foo bar mañana mañana' 

爲什麼?因爲它包含一個星號()(它是represented by surrogate pairs in JavaScript)和一個組合標記(最後mañana中的實際上由兩個符號組成:U + 006E LATIN小字母N和U + 0303合併TILDE)。

代理對出現的順序不能顛倒,否則星號不會再顯示在「反向」字符串中。這就是爲什麼你在前面的例子的輸出中看到了那些��標記。

合併標記總是適用於前一個符號,因此必須將主符號(U + 006E LATIN小字母N)作爲整體標記(U + 0303合併TILDE)。顛倒它們的順序將導致組合標記與字符串中的另一個符號配對。這就是爲什麼示例輸出具有而不是ñ

希望這可以解釋爲什麼到目前爲止發佈的所有答案都是錯誤


要回答你最初的問題 - 在JavaScript如何[正確]反轉字符串 - ,我已經寫了一個小的JavaScript庫,能夠識別Unicode字符串逆轉。它沒有我剛剛提到的任何問題。該圖書館被稱爲Esrever;它的代碼位於GitHub上,它可以在任何JavaScript環境中運行。它帶有一個shell實用程序/二進制文件,所以如果需要,您可以輕鬆地從終端反轉字符串。

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