V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
lisisi
V2EX  ›  JavaScript

js 混合拼接应该用 () 还是 String() 方法处理计算优先级?

  •  
  •   lisisi · 2020-04-02 22:13:17 +08:00 · 2863 次点击
    这是一个创建于 1730 天前的主题,其中的信息可能已经有所发展或是发生改变。

    js 混合拼接的顺序差异,导致结果差别这么大,为什么 js 这么设计?要避免这种混合处理的差异,应该用 () 还是 String() 方法处理计算优先级?

    3 * 0.3 + 1 + 'foo' => 1.9foo
    
    'foo' + 3 * 0.3 + 1 => foo0.8999 九 99999 九 999991
    
    13 条回复    2020-04-03 11:11:31 +08:00
    wobuhuicode
        1
    wobuhuicode  
       2020-04-02 22:16:09 +08:00
    这是合理的设计,JS 不是强类型语言,但是也是有类型的。 + 号是根据类型来进行运算的。
    字符串拼接用 `string${a}` 这种语法就好了
    lisisi
        2
    lisisi  
    OP
       2020-04-02 22:22:30 +08:00
    @wobuhuicode 不是 String() 和 toString() 吗?

    小写 string${a} 是什么语法?
    tyx1703
        3
    tyx1703  
       2020-04-02 22:31:25 +08:00   ❤️ 1
    @lisisi 这是字符串模板,es6 的新语法
    seki
        4
    seki  
       2020-04-02 22:31:32 +08:00   ❤️ 1
    1 楼说的是模板字符串
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings

    如果要问为什么这么设计,答案就是这是 js 糟粕部分。建议完全放弃加号拼接字符串的行为
    xcstream
        5
    xcstream  
       2020-04-02 23:00:31 +08:00
    var a = 1
    var b= `${a}`
    SoloCompany
        6
    SoloCompany  
       2020-04-03 00:03:39 +08:00
    1. 能用 es6 尽量用 template string
    2. 不能用 es6 的字符串串接可以选择
    2.1 开头加一个 '' +
    2.2 用 Array.prototype.join
    rabbbit
        7
    rabbbit  
       2020-04-03 00:43:42 +08:00
    哪个符号优先级高就算哪个

    'foo' + 3 * 3 // "foo9"

    然后不同类型相加会自动转换类型,就全乱套了.

    'a' + 1 // a1
    'a' + true // "atrue"
    'a' + null // "anull"
    'a' + undefined // "aundefined"

    1 + true // 2
    1 + undefined // NaN
    1 + null // 1

    [] + 1// "1"
    [] + 'a' // "a"

    {} + 1 // 1

    ({}) + 1 // "[object Object]1"

    所以最好用模板字符串,而不是加号
    xiangyuecn
        8
    xiangyuecn  
       2020-04-03 00:53:54 +08:00
    乘法优先级比加法高,先运算乘法。相同的加法从左往右一路加过去。这个结果没毛病

    另外一坨 9999 的,其实也没毛病。阅读: http://0.30000000000000004.com/
    xiangyuecn
        9
    xiangyuecn  
       2020-04-03 01:08:50 +08:00


    DOLLOR
        10
    DOLLOR  
       2020-04-03 02:00:10 +08:00
    3 * 0.3 + 1 + 'foo'
    => 0.8999999999999999 + 1 + 'foo'
    => 1.9 + 'foo'
    =>"1.9foo"


    'foo' + 3 * 0.3 + 1
    =>'foo' + 0.8999999999999999 + 1
    =>"foo0.8999999999999999" + 1
    =>"foo0.89999999999999991"

    为什么这么设计,当然是因为先乘除后加减,更符合学过数学的人的思维。
    而“+”既可以作为数学的加法运算,也可以作为字符串的拼接运算。当你用“+”来混合操作 String 和 Number 时,会把 Number 转为 String,再跟另一个 String 做拼接运算。

    要尽量避免用数学操作符来直接操作非 Number 数据类型,以免出现不可预知的隐式转换。
    字符串的拼接尽量用字符串模板(`${}`),避免用“+”拼接。
    citrix
        11
    citrix  
       2020-04-03 09:05:26 +08:00 via Android
    开启 eslint-config-airbnb, 这些编程规范的事情交给 lint 来 fix 就好了
    christin
        12
    christin  
       2020-04-03 10:47:28 +08:00 via iPhone
    +既可以用作数字运算也可以字符串拼接。第一个前面是数字后面是字符就先数字运算再字符拼接。第二个 开始就是字符就一直字符拼接
    crz
        13
    crz  
       2020-04-03 11:11:31 +08:00
    @rabbbit 类型转换的问题模板字符串其实不解决
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2754 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 19ms · UTC 13:44 · PVG 21:44 · LAX 05:44 · JFK 08:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.