如题,需要实现的功能是我有某对象 A,程序中调用 A 时会不可预期地访问其属性,而这个属性他不一定有。可否实现当访问 A 没有的属性时,调用某个函数,给他生成一个动态的返回值。
就是类似像 java 的 @value 和 python 的魔术方法那样的功能,js 有办法实现吗,寻一 js 大佬,谢谢。
1
Cbdy 2020-11-13 08:02:24 +08:00 via Android
Proxy
|
2
Mutoo 2020-11-13 08:03:18 +08:00
使用代理对象,可以拦截 get 方法,加入你需要的逻辑。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy |
3
jingcoco 2020-11-13 08:07:12 +08:00 via iPhone
麻烦的一点的是:自己写个方法不就行了。
代码好看一点的话,可以查查 js 的 get set,封装一下 其他的估计得用到 babel |
4
murmur 2020-11-13 08:18:20 +08:00
这就是被语法糖限制了思路,你直接写一个 getSomeValue 方法不就完了,取属性都调用这个,想怎么改怎么改
|
5
rodrick 2020-11-13 08:31:43 +08:00 1
user?.name === undefined ? 动态的返回值 :user.name
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/%E5%8F%AF%E9%80%89%E9%93%BE |
6
xiangyuecn 2020-11-13 08:41:28 +08:00
js 目测是最简单,代码最简洁,因为取值可以写的太随意了😂
大部分情况下,可这样写( json 中 null 、0 、"" 为逻辑上的无效值): var obj={}; bb=(((obj.aa||{}).cc||[])[123]||{}).zzzzzzzzz||"默认值" 就问还有那种语言可以这样任性😂 |
7
mcfog 2020-11-13 08:46:55 +08:00 via Android
@xiangyuecn 任意非静态强类型语言(也就是布尔以外的值能用来做逻辑运算)、 逻辑运算是短路求值的(几乎所有) 都可以实现一样的事情,没有例外。
真想吹甜度好歹拿 optional chaining 来聊 |
8
free9fw 2020-11-13 08:49:11 +08:00 1
obj?.xxx ?? 'default value'
|
9
xiangyuecn 2020-11-13 09:04:55 +08:00
@mcfog #7 那么,请直接说出哪种语言😂 似乎没有比 js 甜的了吧,不管是 android 还是 ios 原生未封装的代码都得写到脑瘫😂
我 6 楼的那坨 json ( null 、0 、"" 为逻辑上的无效值),取 zzzzzzzzz: {"aa":{"cc":[{"zzzzzzzzz":"值"}]}} {"aa":{"cc":[{}]}} {"aa":{"cc":null}} {"aa":{}} |
10
taro0822 2020-11-13 09:06:49 +08:00
proxy +1
|
12
tyx1703 2020-11-13 09:29:50 +08:00
|
13
yaphets666 2020-11-13 09:32:20 +08:00
es2020 为了解决这个问题 提出了楼上的这种语法
现在一般程序中是这样写 if(a.b&&a.b.c&&a.b.c.d) {....} |
14
SmallTeddy 2020-11-13 09:48:13 +08:00
这里回复一下 proxy 是 es6 新增的原生 可以设置拦截器 设置在 prototype 上 详情可以参考阮一峰写的 es6——https://es6.ruanyifeng.com/#docs/proxy
|
15
DOLLOR 2020-11-13 09:49:35 +08:00
不知道你对“原生方法”定义是啥,但 JS 已经有这种语法了:
aa?.bb?.cc?dd ?? defaultValue 当然你可以用 lodash: _.get(aa, 'bb.cc.dd', defaultValue) 方法已经告诉你了,“调用某个函数,给他生成一个动态的返回值”这种需求就不用我教了吧。 |
16
mcfog 2020-11-13 12:11:28 +08:00
@xiangyuecn 所以我说了静态强类型不行,然后你搬出静态强类型的 java 说不行,确实不行啊
那么我满足你的希望随便说几个吧 写 python 的同学,至少我在填遗留老坑的时候 xx or None 基本写到吐的,(xx or {'foo': None})['foo'] 也能用 写 php 的,在老一点的时代,defined('XX') or die 也是写到吐的, $datasource->getSomeArray() || []也是基本操作 再梳理一下,你说的特性其实只依赖于“布尔以外的类型可以直接参与逻辑运算,并有合理的 falsy 定义” 以及 “上述逻辑运算结果为真时返回原始输入值而不是 true”,这两件事情几乎任何弱类型语言或者是会做动态推断的强类型语言都是满足的,我刚才在路上把后面那个特性说成短路求值了是不准确的,短路求值涉及到类似用法中有副作用的用法,换成你喜欢的 js 的话大概就是 (await request('has_auth')) || alert(‘没有权限!’) 这个样子 |
17
Sunyanzi 2020-11-13 13:05:43 +08:00
@mcfog 既然看到了我问一句题外和楼主问题无关的 ... 关于 #16 的那个 php 的例子 ...
defined( 'XX' ) or die; 不是常规操作吗 ... 空取常量最低也是个 warning ... php8 里升到了 fatal ... 也就是在我的认知里 ... 这种写法并不是「在老一点的时代」才用 ... 相反在未来肯定会越用越多 ... 我想了半天 ... 怎么都觉得这不是操作符能够压得住的事情 ... 所以我想问 ... 是不是说有什么我不知道的方式可以简化这种写法 ..? |
18
mcfog 2020-11-13 14:03:49 +08:00
@Sunyanzi
?额我说“写到吐”就是指这种写法基本操作,不是说有什么更好的,不如说就是因为一个奇怪的语法糖却没啥更好的替代品所以才看到烦…… 还是我没理解对你的疑问? 关于时代新老的问题,主要是慢慢单入口框架或者不把无关文件放在 public 的做法更常见了,所以就不需要这句话了,composer psr 的话就更不用了,psr 规定了声明类的文件不能有副作用 我说的是这个用法是特指什么 IN_DISCUZ 之类的,用一个常量存在性确保文件不被 webserver 错误地执行的用法,否则不会 or die 的吧,还是你说的以后用的更多是$x = defined('XX') or 'default value'; 这种? 这种的话确实随着严重级别上调,用的更多说得通……虽然我是 NOTICE 当 bug 修的选手 |
19
across 2020-11-13 14:08:39 +08:00
js 这种连续问号倒是简洁的,不过问号太多了,总觉得是在嘲讽( dota 后遗症)
|