推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
qq309187341

在 js 中为什么如下方式会找不到值?

  •  
  •   qq309187341 · Jan 4, 2023 · 5388 views
    This topic created in 1399 days ago, the information mentioned may be changed or developed.
    let a = {
    b: {
    c: {
    d: 1
    }
    }
    }

    let z = 'c.d'
    console.log(a.b[z]) // undefined
    为什么?
    如何才能正常找到
    35 replies  •  2023-01-04 20:52:44 +08:00
    DingJZ
    DingJZ
    Jan 4, 2023
    1
    js 本来就不支持这种玩法,可以用第三方的库,lodash 之类的
    qq309187341
    qq309187341
    OP
    Jan 4, 2023
    2
    @DingJZ 不借用第三方,有什么别的写法,如果 z 只有一层 z='c'这样是能找到 c 的,但是再加一层就找不到了
    GressJoe
    GressJoe
    Jan 4, 2023
    3
    eval ,不过容易 boom
    vagary
    vagary
    Jan 4, 2023❤️2
    4
    哈哈哈哈哈
    a={b:{'c.d':1}}; z='c.d'; console.log(a.b[z])能找到
    AV1
    AV1
    Jan 4, 2023
    5
    要么直接用 lodash ,要么自己参考 lodash 的源码自己实现一个 get 方法。
    我倒是好奇有什么编程语言能这样来的?
    thinkershare
    thinkershare
    Jan 4, 2023
    6
    因为 c.d 是一个合法的属性,JS 的对象本质是个 string|symbol-> any 的字典映射。
    chenmobuys
    chenmobuys
    Jan 4, 2023
    7
    啥语言能这样写,这估计是第三方库的处理吧
    wangtian2020
    wangtian2020
    Jan 4, 2023❤️1
    8
    let a = {
    b: {
    c: {
    d: 1,
    },
    },
    }

    let z = 'c.d'
    console.log(eval(`a.b.${z}`)) // 1
    rongchuan
    rongchuan
    Jan 4, 2023❤️5
    9
    @qq309187341
    你声明的'c.d'是一个 string 。a.b[z]是从 a 的 b 属性这个对象上,去找 key 值是 z 的 value ,也就是找 key 值是'c.d'的 value 。显然没有这个 value
    这跟第三方库没关系,你没有理解 key 的概念,.不是随便就能.的
    lower
    lower
    Jan 4, 2023
    10
    a.b['c']['d'] 能找着🤣
    qq309187341
    qq309187341
    OP
    Jan 4, 2023
    11
    @rongchuan 哦。我明白了,c.d 是一个整体,而不是 c 下的 d 。所以合在一起就成了 a.b.'c.d'是这样对吧。哈哈哈哈
    qq309187341
    qq309187341
    OP
    Jan 4, 2023
    12
    @lower 哈哈哈,你这个也行。我理解错了。确实要用你这样的写法才可以
    heishu
    heishu
    Jan 4, 2023
    13
    #8 和 #10 是两种可行的方法,一个是处理字符串,一个是对象依次找值
    pendulum
    pendulum
    Jan 4, 2023
    14
    有点想当然了,JS 根本没有这种特性
    hervey0424
    hervey0424
    Jan 4, 2023
    15
    let a = { 'b.c': 123, b: { c: 456 } };
    console.log(a.b.c); // 456
    console.log(a['b.c']); //123
    KMpAn8Obw1QhPoEP
    KMpAn8Obw1QhPoEP
    Jan 4, 2023 via Android
    16
    我居然看了好久才明白你的代码意图是什么。。。。所以反过来我想问的是 哪个语言能支持你这样的写法取值?
    mynameislihua
    mynameislihua
    Jan 4, 2023
    17
    lodash get
    webcape233
    webcape233
    Jan 4, 2023 via iPhone
    18
    什么样的需求这是...
    zhouyg
    zhouyg
    Jan 4, 2023
    19
    根本原因 js 不知道你传入的 c.d 是一个整体的字符串 key 还是可以分割的访问 key ,这里是有歧义的。支持这个特性也很简单,那就是在语言层面新增一个语法来消除这个歧义
    1t1y1ILnW0x5nt47
    1t1y1ILnW0x5nt47
    Jan 4, 2023
    20
    可以用 Object.defineProperty 劫持它的 key,然后把 c.d 转化一下
    caocong
    caocong
    Jan 4, 2023❤️2
    21
    z.split('.').reduce((res, val)=>res[val],a.b)
    venfiw
    venfiw
    Jan 4, 2023
    22
    let a = {
    b: {
    c: { d: 1}
    }
    }

    let z = 'c.d';
    console.log(a.b[z]) // undefined
    console.log(Object.keys(a.b))

    你可以通过这个可以看到 a.b 里只有一个键值:'c' 并没有'c.d'
    如果你把 c 改为‘c.d' 那么 a.b[z]就可以正常输出
    777777
    777777
    Jan 4, 2023
    23
    写 go 的,看见这种语法直接震惊
    aust
    aust
    Jan 4, 2023
    24
    这种写法你要打印的写法等同于
    {
    "c.d": 1
    } 而不是 {
    c: {
    d: 1
    }
    }
    Arthit
    Arthit
    Jan 4, 2023
    25
    console.log(a.b["c"]["d"]);
    libook
    libook
    Jan 4, 2023❤️1
    26
    题主提供了一个典型的 bug 案例。因为实际工程上,更多的情况是我们会预期给 z 传入单个字段名,但意外传入路径就 bug 了。所以通常这样用需要小心,如果 z 是用户输入的要做好校验。
    weixiangzhe
    weixiangzhe
    Jan 4, 2023
    27
    那就是手写个 get
    ```js
    function get(obj, path, def) {
    var fullPath = path
    .replace(/\[/g, '.')
    .replace(/]/g, '')
    .split('.')
    .filter(Boolean);

    return fullPath.every((step)=>{
    return !(step && (obj = obj[step]) === undefined);
    }) ? obj : def;
    }

    let a = {
    b: {
    c: {
    d: 1
    }
    }
    }

    let z = 'c.d'
    // console.log(a.b[z]) // undefined


    console.log(get(a,'b.c.d'))


    ```
    horseInBlack
    horseInBlack
    Jan 4, 2023
    28
    const {
    b: {
    c: { d: z },
    },
    } = a;

    console.log(z);

    连续解构赋值
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
    chenyu0532
    chenyu0532
    Jan 4, 2023
    29
    连续解构赋值吧。
    你们玩的是真 high ,学习归学习,工作里我可不敢这么用,怕同事打我
    z782297190
    z782297190
    Jan 4, 2023
    30
    字符串 . 和 属性访问器 . 是不同的,js 引擎不认字符串 .
    KMpAn8Obw1QhPoEP
    KMpAn8Obw1QhPoEP
    Jan 4, 2023 via Android
    31
    @777777 小场面 莫慌莫慌 写 JS 的震惊。。
    mwjz
    mwjz
    Jan 4, 2023
    32
    let a = {
    b: {
    c: {
    d: 1
    }
    }
    }

    let z = 'c.d'

    const c = z.split('.').reduce((pre, curr) => pre[curr], a.b);
    imingyu
    imingyu
    Jan 4, 2023
    33
    为什么?
    因为你语法写错了!
    为什么语法是 a.b.c.d 而不是 a.b['c.d']?
    因为规定!
    lynan
    lynan
    Jan 4, 2023
    34
    https://imgur.com/EHwVAgx.png
    这样写才可以取到值,因为在[]里是 key 名
    lynan
    lynan
    Jan 4, 2023
    35
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5001 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 09:09 · PVG 17:09 · LAX 01:09 · JFK 04:09
    ♥ Do have faith in what you're doing.