V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
xilixjd
V2EX  ›  问与答

一个 JS 基础问题 [42] < ['43'] 和 [42] < ['043']

  •  
  •   xilixjd · 2017-05-05 16:46:50 +08:00 · 2209 次点击
    这是一个创建于 2763 天前的主题,其中的信息可能已经有所发展或是发生改变。

    这是《你不知道的 JS 》上的内容,书上的解释如下:

    比较双方首先调用 toPrimitive,如果结果出现非字符串,就根据 ToNumber 规则将双方强制类型转换为数字进行比较

    [42] < ['43'] // true
    

    a 和 b 并没有转换为数字,因为 toPrimitive 返回的是字符串,所以这里比较的是 “ 42 ” 和 "043" 这两个字符串

    [42] < ['043'] // false
    

    我想问的是,第一个表达式为什么 toPrimitive 会转换为数字,而第二个表达式却说并没有转换为数字?

    第 1 条附言  ·  2017-05-05 19:29:12 +08:00
    PS:在中册的 p89 页
    14 条回复    2017-05-05 20:34:21 +08:00
    MinonHeart
        1
    MinonHeart  
       2017-05-05 19:08:19 +08:00
    [42].toString() -> '42'
    ['43'].toString() -> '43'

    '42'.charCodeAt(0) == '43'.charCodeAt(0)
    '42'.charCodeAt(1) < '43'.charCodeAt(1)

    所以 [42] < ['43']
    xilixjd
        2
    xilixjd  
    OP
       2017-05-05 19:23:41 +08:00
    @MinonHeart 好的,明白了,那书上描述是不是写错了,并不是转换为数字啊
    FrankFang128
        3
    FrankFang128  
       2017-05-05 19:24:56 +08:00   ❤️ 2
    神经病才比较这两个东西
    Kisesy
        4
    Kisesy  
       2017-05-05 19:25:10 +08:00
    不太了解 js ,不过我觉得也许 js 默认并不把八进制的字符解析成整数
    xilixjd
        5
    xilixjd  
    OP
       2017-05-05 19:30:31 +08:00
    @FrankFang128 实际上书上并没有刻意比较这两个东西,只是说明了一下比较符号(<,>)的性质
    xilixjd
        6
    xilixjd  
    OP
       2017-05-05 19:32:06 +08:00
    @Kisesy 应该是 1 楼所说的原因,书上可能写错了
    因为 [42] < [256] 为 false
    FrankFang128
        7
    FrankFang128  
       2017-05-05 19:36:19 +08:00
    任何不同类型的值,都不要直接比较,没有任何意义。
    noe132
        8
    noe132  
       2017-05-05 19:37:07 +08:00
    参考
    http://www.ecma-international.org/ecma-262/7.0/index.html#sec-abstract-relational-comparison

    x < y
    首先将 x 和 y 调用 toPrimitive(x ,hint number) toPrimitive(y ,hint number)
    保存为 px py

    根据上面情况,toPrimitive 会返回对 x 和 y 先调用 valueOf
    当返回结果类型是 Object,或者不能调用 valueOf
    则调用 toString
    当返回结果类型是 Object,或者不能调用 toString
    抛出 TypeError

    [42].toString() // "42"
    ['43'].toString() // "43"

    根据上面情况,当 px py 都为 string 时


    如果 py 是 px 的 prefix 返回 false.
    如果 px 是 py 的 prefix 返回 true.

    如果都不,则对 px 和 py 进行一个字符一个字符的对比
    "42" "43"
    第一位 '4' 相同
    第二位'2' 和 '3'的 charcode 比较 '2'比'3'的 charcode 小
    返回 true


    类似的
    [42] < ['043'] 的比较,前几步类似,在后面比较时'4' 和 '0'的 charcode 比较 '4'大于 '0'
    所以结果是 false
    MinonHeart
        9
    MinonHeart  
       2017-05-05 19:38:25 +08:00 via iPhone
    @xilixjd 左右两边 toPrimitive 转换后都是字符串
    noe132
        10
    noe132  
       2017-05-05 19:39:57 +08:00
    Q: 我想问的是,第一个表达式为什么 toPrimitive 会转换为数字,而第二个表达式却说并没有转换为数字?

    A: 实际上,第一个表达式 toPrimitive 也是字符串。比较的规则在 ecma-262 里,查规范就知道内部是怎么进行比较的了。只是你感觉好像转化成了数值。
    jamesxu
        11
    jamesxu  
       2017-05-05 19:46:18 +08:00 via iPhone
    js 是个蛋疼的语言
    xilixjd
        12
    xilixjd  
    OP
       2017-05-05 19:47:13 +08:00
    @noe132
    @MinonHeart
    好的,了解了
    sensui7
        13
    sensui7  
       2017-05-05 20:31:40 +08:00
    @xilixjd 这书中文版翻译的很差,
    sensui7
        14
    sensui7  
       2017-05-05 20:34:21 +08:00
    而且, 很多东西对实际编程 js 没多大用.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5814 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 03:13 · PVG 11:13 · LAX 19:13 · JFK 22:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.