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 2
哈哈哈哈哈
a={b:{'c.d':1}}; z='c.d'; console.log(a.b[z])能找到 |
5
DOLLOR 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 1
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 5
@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
enchilada2020 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 2
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 1
题主提供了一个典型的 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')) ``` |
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
enchilada2020 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)
|