在字符串上调用[] .reverse

Hai*_*Hai 7 javascript

为什么

[].reverse.call("string");
Run Code Online (Sandbox Code Playgroud)

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

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

小智 8

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


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

var s = "string";

var s2 = [].slice.call(s).reverse().join('');
Run Code Online (Sandbox Code Playgroud)

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


Mat*_*ens 5

以下技术(或类似)通常用于在JavaScript中反转字符串:

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

事实上,到目前为止发布的所有答案都是这种模式的变体.但是,此解决方案存在一些问题.例如:

naiveReverse('foo  bar');
// ? 'rab ?? oof'
// Where did the `` symbol go? Whoops!
Run Code Online (Sandbox Code Playgroud)

如果您想知道为什么会这样,请阅读JavaScript的内部字符编码.(TL; DR: is an astral symbol, and JavaScript exposes it as two separate code units.)

But there’s more:

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

A good string to test string reverse implementations is the following:

'foo  bar mañana man?ana'
Run Code Online (Sandbox Code Playgroud)

Why? Because it contains an astral symbol ()(由JavaScript中的代理对表示)和一个组合标记(n?在最后一个man?ana实际上由两个符号组成:U + 006E LATIN SMALL LETTER N和U + 0303 COMBINING TILDE).

代理对出现的顺序不能反转,否则星形符号将不再出现在"反向"字符串中.这就是您??在前一个示例的输出中看到这些标记的原因.

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

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


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

var input = 'foo  bar mañana man?ana';
esrever.reverse(input);
// ? 'anan?am anañam rab  oof'
Run Code Online (Sandbox Code Playgroud)