"100" < "99" = true

122 阅读2分钟

缘由

Chrome浏览器的版本号突破100,由此引发的版本号比较问题,有一种写法最终执行结果就是

"100" < "99"

但是结果并不符合预期返回 false ,相反结果是 true 。

问题

问题在于这很不符合直觉,更符合直觉的方式是各自都转成数字然后再比较。

验证

以下是 Chrome 验证过程

"100" < "99"
true
"100".charCodeAt(0)
49
"99".charCodeAt(0)
57
"100".charCodeAt(0) < "99".charCodeAt(0)
true

返回结果确确实实是 true ,"100" 小于 "99"。

原理

1. 参考小于号 Less than (<)中的描述

The operands are compared using the [Abstract Relational Comparison](https://tc39.es/ecma262/#sec-abstract-relational-comparison) algorithm, which is roughly summarized below:

-   First, objects are converted to primitives using [`Symbol.ToPrimitive`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive) with the `hint` parameter be `'number'`.

-   If both values are strings, they are compared as strings, based on the values of the Unicode code points they contain.

-   Otherwise JavaScript attempts to convert non-numeric types to numeric values:

    -   Boolean values `trueand `falseare converted to 1 and 0 respectively.
    -   `nullis converted to 0.
    -   `undefined` is converted to `NaN`.
    -   Strings are converted based on the values they contain, and are converted as `NaN` if they do not contain numeric values.

-   If either value is [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN), the operator returns `false`.

-   Otherwise the values are compared as numeric values.

如果两个值都是字符串,则根据它们包含的 Unicode 代码点的值进行比较。

2. 参考Abstract Relational Comparison中的描述(仅截取字符串比较相关描述)

 If Type(px) is String and Type(py) is String, then

  1. If IsStringPrefix(pypx) is true, return false.
  2.  If IsStringPrefix(pxpy) is true, return true.
  3.  Let k be the smallest non-negative integer such that the code unit at index k within px is different from the code unit at index k within py. (There must be such a k, for neither String is a prefix of the other.)
  4.  Let m be the integer that is the numeric value of the code unit at index k within px.
  5.  Let n be the integer that is the numeric value of the code unit at index k within py.
  6.  If m < n, return true. Otherwise, return false.

总结一下

  1. 前两条描述的是如果 x 是 y 前缀,则返回 true,否则是 false
  2. 后三条描述的是 x 、 y 不互为前缀,就逐个比较每个字符对应的 Unicode