JavaScript 有没有办法当查询某对象不存在某属性时返回一个默认值?

2020-11-13 07:54:32 +08:00
 black11black

如题,需要实现的功能是我有某对象 A,程序中调用 A 时会不可预期地访问其属性,而这个属性他不一定有。可否实现当访问 A 没有的属性时,调用某个函数,给他生成一个动态的返回值。

就是类似像 java 的 @value 和 python 的魔术方法那样的功能,js 有办法实现吗,寻一 js 大佬,谢谢。

1718 次点击
所在节点    问与答
20 条回复
Cbdy
2020-11-13 08:02:24 +08:00
Proxy
Mutoo
2020-11-13 08:03:18 +08:00
使用代理对象,可以拦截 get 方法,加入你需要的逻辑。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
jingcoco
2020-11-13 08:07:12 +08:00
麻烦的一点的是:自己写个方法不就行了。
代码好看一点的话,可以查查 js 的 get set,封装一下
其他的估计得用到 babel
murmur
2020-11-13 08:18:20 +08:00
这就是被语法糖限制了思路,你直接写一个 getSomeValue 方法不就完了,取属性都调用这个,想怎么改怎么改
rodrick
2020-11-13 08:31:43 +08:00
xiangyuecn
2020-11-13 08:41:28 +08:00
js 目测是最简单,代码最简洁,因为取值可以写的太随意了😂

大部分情况下,可这样写( json 中 null 、0 、"" 为逻辑上的无效值):
var obj={};

bb=(((obj.aa||{}).cc||[])[123]||{}).zzzzzzzzz||"默认值"

就问还有那种语言可以这样任性😂
mcfog
2020-11-13 08:46:55 +08:00
@xiangyuecn 任意非静态强类型语言(也就是布尔以外的值能用来做逻辑运算)、 逻辑运算是短路求值的(几乎所有) 都可以实现一样的事情,没有例外。

真想吹甜度好歹拿 optional chaining 来聊
free9fw
2020-11-13 08:49:11 +08:00
obj?.xxx ?? 'default value'
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":{}}
taro0822
2020-11-13 09:06:49 +08:00
proxy +1
wenzichel
2020-11-13 09:28:01 +08:00
@free9fw #8 正解
tyx1703
2020-11-13 09:29:50 +08:00
yaphets666
2020-11-13 09:32:20 +08:00
es2020 为了解决这个问题 提出了楼上的这种语法
现在一般程序中是这样写 if(a.b&&a.b.c&&a.b.c.d) {....}
SmallTeddy
2020-11-13 09:48:13 +08:00
这里回复一下 proxy 是 es6 新增的原生 可以设置拦截器 设置在 prototype 上 详情可以参考阮一峰写的 es6——https://es6.ruanyifeng.com/#docs/proxy
DOLLOR
2020-11-13 09:49:35 +08:00
不知道你对“原生方法”定义是啥,但 JS 已经有这种语法了:
aa?.bb?.cc?dd ?? defaultValue

当然你可以用 lodash:
_.get(aa, 'bb.cc.dd', defaultValue)

方法已经告诉你了,“调用某个函数,给他生成一个动态的返回值”这种需求就不用我教了吧。
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(‘没有权限!’)

这个样子
Sunyanzi
2020-11-13 13:05:43 +08:00
@mcfog 既然看到了我问一句题外和楼主问题无关的 ... 关于 #16 的那个 php 的例子 ...

defined( 'XX' ) or die; 不是常规操作吗 ... 空取常量最低也是个 warning ... php8 里升到了 fatal ...

也就是在我的认知里 ... 这种写法并不是「在老一点的时代」才用 ... 相反在未来肯定会越用越多 ...

我想了半天 ... 怎么都觉得这不是操作符能够压得住的事情 ...

所以我想问 ... 是不是说有什么我不知道的方式可以简化这种写法 ..?
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 修的选手
across
2020-11-13 14:08:39 +08:00
js 这种连续问号倒是简洁的,不过问号太多了,总觉得是在嘲讽( dota 后遗症)
Sunyanzi
2020-11-13 18:35:14 +08:00
@mcfog 没有没有 ... 应该是我理解的问题 ...

我的侧重点在那句「在老一点的时代」 ... 也不知道怎么就以为是说新的时代就有更方便的写法了 ...

原来是说新的时代里这种写法不那么常见了 ... 那确实没毛病 ...

另 ... Notice 当 bug 修是没错的 ... error_reporting( E_ALL ); 是自信心和技术力的表现 ...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/724644

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX