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

JS 创建对象字面量时,能否动态决定 Key 是否应该存在

  •  
  •   meteor957 · 2020-06-02 11:13:10 +08:00 · 1827 次点击
    这是一个创建于 1640 天前的主题,其中的信息可能已经有所发展或是发生改变。

    const v = null; const o = { name: v }

    在创建字面量时,是否有优雅的语法达到:如果 v 是 null 则 o 没有 name 这个属性 的效果。

    注意:是创建时,而不是创建对象后,再做一些判断。

    16 条回复    2020-06-03 11:32:22 +08:00
    onfuns
        1
    onfuns  
       2020-06-02 11:24:03 +08:00 via iPhone
    用 eval
    Mutoo
        2
    Mutoo  
       2020-06-02 11:24:51 +08:00
    字面量的话没办法。但是事后去掉 null/undefined 还是比较简单的。例如用 lodash 的 pickBy
    const isNotNull = value=>value!==null;
    const o = _.pickBy({ name: v }, isNotNull);
    hronro
        3
    hronro  
       2020-06-02 11:26:51 +08:00   ❤️ 2
    const o = { ...(v == null ? {} : {name: v}) }
    meteor957
        4
    meteor957  
    OP
       2020-06-02 11:29:52 +08:00
    @hronro 如果有多个属性,并且判断条件不一致 ....
    meteor957
        5
    meteor957  
    OP
       2020-06-02 11:33:43 +08:00
    @Mutoo 如果不是所有属性都是判断 null 呢,属性 a 为 null 时不存在,属性 b 为 5 时才存在
    noe132
        6
    noe132  
       2020-06-02 11:47:17 +08:00
    判断方法不一致就老老实实写判断,不管是 if 还是三元
    多不了几行代码的

    题外一句,这种数据结构不太符合直觉,通常会有更好的处理方式
    meteor957
        7
    meteor957  
    OP
       2020-06-02 11:56:07 +08:00
    @noe132 常用于 url 的 query 对象,打个比方,排序字段:升序 1 、降序 2,*不传不排序*
    optional
        8
    optional  
       2020-06-02 11:59:28 +08:00
    在用的时候去掉 null/undefined 是最好的。
    另外后端比如 java,很难区分没传还是 null 。
    otakustay
        9
    otakustay  
       2020-06-02 12:07:12 +08:00
    用的时候剔除+1,可以用 lodash 的 omitBy 或者 pickBy 实现
    你这样子动态的对象结构,对强类型的工具不友好,对运行性能也不友好,实在没有太多必要
    robinlovemaggie
        10
    robinlovemaggie  
       2020-06-02 12:13:01 +08:00
    axios 的内部 param 处理就是按你这个思路走的,可以去看源码实现
    Mutoo
        11
    Mutoo  
       2020-06-02 12:29:00 +08:00
    @meteor957 pickBy 的 callback 传入 (value, key) 返回 true 表示保留,false 表示忽略。逻辑自己组装,非常灵活。
    Cbdy
        12
    Cbdy  
       2020-06-02 12:41:02 +08:00 via Android
    Marstin
        13
    Marstin  
       2020-06-02 14:15:15 +08:00
    手写一个_create 来赋值?

    Object.prototype_create(d){
    return d.removeNull();
    }
    yaphets666
        14
    yaphets666  
       2020-06-02 14:29:13 +08:00
    先判断 v 的值 再创建对象 o
    autoxbc
        15
    autoxbc  
       2020-06-03 10:07:57 +08:00   ❤️ 1
    URI.js 是个专门处理 url 对象的工具,其作者在 api 设计上造诣很深,刚好针对楼主这种需求

    // remove multiple values with value filter
    uri.search("?hello=world&hello=mars&foo=bar&mine=true&a=1&a=2&a=3");
    uri.removeSearch({hello: "world", foo: undefined, a: ["1", "3"]});
    // uri == "?hello=mars&mine=true&a=2"

    这里 removeSearch 方法通过输入一个字面量对象一次性从 URI 对象中移除全部符合条件的参数,也就是楼主所谓的条件置空

    这里有详细手册
    https://medialize.github.io/URI.js/docs.html
    dallaslu
        16
    dallaslu  
       2020-06-03 11:32:22 +08:00
    @meteor957 #4

    const o = { ...(v ? {name: v} : {}), ...(v2 ? {email:v2} : {}) }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1494 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 23:56 · PVG 07:56 · LAX 15:56 · JFK 18:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.