在字符串上调用[] .reverse

时间:2012-01-15 00:18:16

标签: javascript

为什么

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

在调用字符串上的所有其他数组方法时失败(firefox中的错误,即返回chrome中的原始字符串)?

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

3 个答案:

答案 0 :(得分:8)

因为.reverse()修改了一个数组,并且字符串是不可变的。


您可以借用Array.prototype.slice转换为数组,然后反向并加入它。

var s = "string";

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

请注意,在旧版本的IE中,您无法操纵像Array这样的字符串。

答案 1 :(得分: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拉丁文小写字母N和U + 0303组合TILDE)。

代理对出现的顺序无法逆转,否则星号符号将不再出现在“反向”字符串中。这就是为什么你在上一个例子的输出中看到那些��标记的原因。

组合标记始终应用于上一个符号,因此您必须将主符号(U + 006E LATIN SMALL LETTER N)作为组合标记(U + 0303 COMBINING TILDE)整体处理。反转它们的顺序将使组合标记与字符串中的另一个符号配对。这就是为什么示例输出有而不是ñ

希望这可以解释为什么到目前为止发布的所有答案都错误


要回答您的初始问题 - 如何[正确]反转JavaScript中的字符串 - ,我编写了一个能够识别Unicode的字符串反转的小型JavaScript库。它没有我刚才提到的任何问题。该库名为Esrever;它的代码在GitHub上,几乎适用于任何JavaScript环境。它带有一个shell实用程序/二进制文件,因此如果需要,您可以轻松地从终端中反转字符串。

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

答案 2 :(得分:4)

请参阅@am,我不知道为什么它不起作用。但是,如果您想知道如何完成此操作,请先将其转换为数组:

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