
1 DingJZ 2023-01-04 10:40:59 +08:00 js 本来就不支持这种玩法,可以用第三方的库,lodash 之类的 |
2 qq309187341 OP @DingJZ 不借用第三方,有什么别的写法,如果 z 只有一层 z='c'这样是能找到 c 的,但是再加一层就找不到了 |
3 GressJoe 2023-01-04 10:43:20 +08:00 eval ,不过容易 boom |
4 vagary 2023-01-04 10:46:24 +08:00 哈哈哈哈哈 a={b:{'c.d':1}}; z='c.d'; console.log(a.b[z])能找到 |
5 AV1 2023-01-04 10:47:21 +08:00 要么直接用 lodash ,要么自己参考 lodash 的源码自己实现一个 get 方法。 我倒是好奇有什么编程语言能这样来的? |
6 thinkershare 2023-01-04 10:48:19 +08:00 因为 c.d 是一个合法的属性,JS 的对象本质是个 string|symbol-> any 的字典映射。 |
7 chenmobuys 2023-01-04 10:49:41 +08:00 啥语言能这样写,这估计是第三方库的处理吧 |
8 wangtian2020 2023-01-04 10:53:34 +08:00 let a = { b: { c: { d: 1, }, }, } let z = 'c.d' console.log(eval(`a.b.${z}`)) // 1 |
9 rongchuan 2023-01-04 10:53:51 +08:00 @qq309187341 你声明的'c.d'是一个 string 。a.b[z]是从 a 的 b 属性这个对象上,去找 key 值是 z 的 value ,也就是找 key 值是'c.d'的 value 。显然没有这个 value 这跟第三方库没关系,你没有理解 key 的概念,.不是随便就能.的 |
10 lower 2023-01-04 10:54:56 +08:00 a.b['c']['d'] 能找着 |
11 qq309187341 OP @rongchuan 哦。我明白了,c.d 是一个整体,而不是 c 下的 d 。所以合在一起就成了 a.b.'c.d'是这样对吧。哈哈哈哈 |
12 qq309187341 OP @lower 哈哈哈,你这个也行。我理解错了。确实要用你这样的写法才可以 |
13 heishu 2023-01-04 11:31:27 +08:00 #8 和 #10 是两种可行的方法,一个是处理字符串,一个是对象依次找值 |
14 pendulum 2023-01-04 11:34:18 +08:00 有点想当然了,JS 根本没有这种特性 |
15 hervey0424 2023-01-04 11:38:37 +08:00 let a = { 'b.c': 123, b: { c: 456 } }; console.log(a.b.c); // 456 console.log(a['b.c']); //123 |
16 KMpAn8Obw1QhPoEP 2023-01-04 11:41:19 +08:00 via Android 我居然看了好久才明白你的代码意图是什么。。。。所以反过来我想问的是 哪个语言能支持你这样的写法取值? |
17 mynameislihua 2023-01-04 11:44:09 +08:00 lodash get |
18 webcape233 2023-01-04 11:49:37 +08:00 via iPhone 什么样的需求这是... |
19 zhouyg 2023-01-04 11:55:56 +08:00 根本原因 js 不知道你传入的 c.d 是一个整体的字符串 key 还是可以分割的访问 key ,这里是有歧义的。支持这个特性也很简单,那就是在语言层面新增一个语法来消除这个歧义 |
20 1t1y1ILnW0x5nt47 2023-01-04 11:57:02 +08:00 可以用 Object.defineProperty 劫持它的 key,然后把 c.d 转化一下 |
21 caocong 2023-01-04 12:06:32 +08:00 z.split('.').reduce((res, val)=>res[val],a.b) |
22 venfiw 2023-01-04 12:52:02 +08:00 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]就可以正常输出 |
23 777777 2023-01-04 14:32:53 +08:00 写 go 的,看见这种语法直接震惊 |
24 aust 2023-01-04 14:43:14 +08:00 这种写法你要打印的写法等同于 { "c.d": 1 } 而不是 { c: { d: 1 } } |
25 Arthit 2023-01-04 16:12:20 +08:00 console.log(a.b["c"]["d"]); |
26 libook 2023-01-04 16:18:47 +08:00 题主提供了一个典型的 bug 案例。因为实际工程上,更多的情况是我们会预期给 z 传入单个字段名,但意外传入路径就 bug 了。所以通常这样用需要小心,如果 z 是用户输入的要做好校验。 |
27 weixiangzhe 2023-01-04 16:54:12 +08:00 那就是手写个 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')) br />``` |
28 horseInBlack 2023-01-04 17:06:32 +08:00 const { b: { c: { d: z }, }, } = a; console.log(z); 连续解构赋值 https://developer.mozilla.org/zh-CN/docs/Web/Javascript/Reference/Operators/Destructuring_assignment |
29 chenyu0532 2023-01-04 18:07:58 +08:00 连续解构赋值吧。 你们玩的是真 high ,学习归学习,工作里我可不敢这么用,怕同事打我 |
30 z782297190 2023-01-04 18:19:48 +08:00 字符串 . 和 属性访问器 . 是不同的,js 引擎不认字符串 . |
31 KMpAn8Obw1QhPoEP 2023-01-04 18:29:18 +08:00 via Android @777777 小场面 莫慌莫慌 写 JS 的震惊。。 |
32 mwjz 2023-01-04 18:38:39 +08:00 let a = { b: { c: { d: 1 } } } let z = 'c.d' const c = z.split('.').reduce((pre, curr) => pre[curr], a.b); |
33 imingyu 2023-01-04 18:42:57 +08:00 为什么? 因为你语法写错了! 为什么语法是 a.b.c.d 而不是 a.b['c.d']? 因为规定! |
34 lynan 2023-01-04 20:51:57 +08:00 https://imgur.com/EHwVAgx.png 这样写才可以取到值,因为在[]里是 key 名 |
35 lynan 2023-01-04 20:52:44 +08:00 [Imgur]( https://imgur.com/EHwVAgx) |