我从一本书中看到这段代码:
var a = "one";
var b = "four";
a>b; // will return true
但它没有提到为什么“一”比“四”大。我试过了c = "a"
,它比a和b小。我想知道 JavaScript 如何比较这些字符串。
我从一本书中看到这段代码:
var a = "one";
var b = "four";
a>b; // will return true
但它没有提到为什么“一”比“四”大。我试过了c = "a"
,它比a和b小。我想知道 JavaScript 如何比较这些字符串。
因为,在许多编程语言中,字符串是按字典顺序比较的。
您可以将其视为字母排序的更高级版本,不同之处在于字母排序仅涵盖 26 个字符a
到z
.
这个答案是对一个Java问题,但逻辑是完全一样的。另一个好方法:String Compare "Logic"。
“one”以“o”开头,“four”以“f”开头,“o”在字母表中比“f”晚,因此“one”大于“four”。有关JavaScript 字符串比较的一些不错的示例,请参阅此页面(附有解释!)。
Javascript 对>运算符使用字典顺序。'f' 继续 'o' 所以比较"one" > "four"返回true
在ECMAScript语言规范的第11版的“抽象关系比较”条款定义了如何计算x < y
。当表达式被还原(即x > y
)时,我们应该计算结果y < x
。
所以要解决"one" > "four"
我们必须解决"four" < "one"
。
同一个条款是这样说的:
字符串的比较对代码单元值序列使用简单的字典顺序。
这如果两个操作数都是字符串:
- 如果 Type(px) 是 String 并且 Type(py) 是 String,那么
- 如果IsStringPrefix (py, px) 为真,则返回假。
- 如果IsStringPrefix (px, py) 为真,则返回真。
- 令 k 为最小的非负整数,使得 px 内索引 k 处的代码单元与 py 内索引 k 处的代码单元不同。(必须有这样的 ak,因为 String 都不是另一个的前缀。)
- 让 m 是整数,它是 px 内索引 k 处代码单元的数值。
- 设 n 是整数,它是 py 中索引 k 处代码单元的数值。
- 如果 m < n,则返回 true。否则,返回false。
(我们可以放心地忽略此示例的前两点)
那么让我们看看“四”的代码单元:
[..."four"].map(c => c.charCodeAt(0));
//=> [102, 111, 117, 114]
而对于“一”:
[..."one"].map(c => c.charCodeAt(0));
//=> [111, 110, 101]
所以现在我们必须找到k的值(从 0 开始),其中m[k]和n[k]都不同:
| | 0 | 1 | 2 | 3 |
|---|-----|-----|-----|-----|
| m | 102 | 111 | 117 | 114 |
| n | 111 | 110 | 101 | |
我们可以看到在 0 处m[0]和n[0]是不同的。
由于m[0] < n[0]为真,"four" < "one"
则为真,因此"one" > "four"
为真。
"☂︎" < "☀︎"
回报?[..."☂︎"].map(c => c.charCodeAt(0))
//=> [9730, 65038]
[..."☀︎"].map(c => c.charCodeAt(0))
//=> [9728, 65038]
| | 0 | 1 |
|---|------|-------|
| m | 9730 | 65038 |
| n | 9728 | 65038 |
既然9730 < 9728
是假的,那"☂︎" < "☀︎"
就是假的,这很好,因为雨并不比太阳好(显然;)。
当您<=
在 JavaScript 中使用像字符串这样的关系运算符时,您是在比较它们的底层 Unicode 代码单元¹,从头开始一次一个,第一次发现任何差异时停止。"one" > "four"
为真,因为"o"
(代码单元 111)大于至"f"
(代码单元 102)。由于在第一个字符中发现差异,其余字符将被忽略。如果有"fb" > "fa"
,"f"
则将比较两个s,发现相同,然后比较每个字符串("b"
和"a"
)的下一个字母。如果字符串的长度不同并且较长的字符串从较短的字符串开始,则较短的字符串“小于”较长的字符串 ( "aaa" < "aaab"
is true
)。
这曾经被规范中的抽象关系比较操作所涵盖,但现在是IsLessThan操作。
¹ 关系运算符使用代码单元这一事实是不将它们与字符串一起使用的一个很好的理由,因为在许多情况下,代码单元顺序不能很好地映射到人们基于他们的语言的期望("é"
< "z"
is false
,这可能没什么意义对讲法语的人);相反,使用localeCompare
, 可能带有一些可选设置,以便与字符串包含的语言进行适当的比较("é".localeCompare("z", "fr") < 0
is true
,因为在语言环境中以正确的词典顺序é
出现在前面)。z
"fr"