我在看别人代码的时候,有看到代码是这样写的
function(){
fn&&fn()
}
大概意思是这么个意思,但是这我感觉这样写好像没意义,有带佬能指点一下吗
1
VWMMWV OP 要是 fn 不存在那肯定会直接报错 fn undefined ;要是 fn 存在;那直接执行 fn() 就好了
|
2
szq8014 2020-06-23 11:56:00 +08:00
只有有 fn 这个变量的时候才会当成函数执行,否则不执行,console 就不会报错了?
|
3
cjc2017 2020-06-23 11:56:03 +08:00 2
自抛自扣??
|
4
bojackhorseman 2020-06-23 11:56:45 +08:00
处理回调
|
5
seeker 2020-06-23 11:56:59 +08:00 3
if (fn) {
fn() } |
6
Perry 2020-06-23 12:01:41 +08:00
大部分情况是 1 楼这个意思,如果 fn 是 undefined 就不执行 fn()。React 针对 optional callback 会这么写。
|
8
ochatokori 2020-06-23 12:24:17 +08:00 via Android
@VWMMWV #1 错了,fn 不存在就什么都不做,不会报错,fn 存在才尝试执行 fn
|
9
rioshikelong121 2020-06-23 12:29:46 +08:00
短路。另外不会报错。
|
10
shenyu1996 2020-06-23 12:30:33 +08:00
if (fn) {
fn() } |
11
shenyu1996 2020-06-23 12:32:04 +08:00
没注意和 5 楼重复了 用 if 语句就更好理解了吧
|
12
dremy 2020-06-23 12:37:43 +08:00 via iPhone
这种不标准的写法完全是负分,竟然还有人用来装 B…
|
13
xiangyuecn 2020-06-23 12:41:22 +08:00 3
@dremy #12 在 js 里面,这是标准的。大幅减少代码量,比三目运算更直接了当。别的语言大同小异:fn?.xx()
|
15
dremy 2020-06-23 12:50:30 +08:00
@xiangyuecn 大幅减少代码量?可读性的下降之后,代码量的减少有意义吗?这分明是不能区分判断语句和条件表达式的区别导致的
与其: abc && fn && fn(abc) 不如: if (abc && fn) { fn(abc) } |
17
chiu 2020-06-23 12:54:54 +08:00
短路, bash 里常见
|
18
northernlights 2020-06-23 13:00:20 +08:00
不会报错,fn 即!!fn 。这个写法通常在回调里用。有 fn 就执行 fn
|
20
xiangyuecn 2020-06-23 13:02:31 +08:00
@dremy #15 比三目运算更直接了当:可读性更好的意思😏
|
21
Vogan 2020-06-23 13:03:51 +08:00
@dremy 你那是 jsx 。在调用 props 的函数的时候,很正常。this.props.cb && this.props.cb()
|
22
taxiaohaohhh 2020-06-23 13:04:43 +08:00
@dremy 负分哪里得出的,还有这个写法怎么装逼的
|
23
xiangyuecn 2020-06-23 13:06:41 +08:00
很多古董语言开始没有简写的 null 判断,一堆 if else,非常难看,后面陆续都有了可空类型,普遍简写成一句话,类似:nullObj?.call(),还是 js 的语义上更直白 obj&&obj.call()
|
24
Vegetable 2020-06-23 13:06:43 +08:00
就是一个 or 运算符,前者为 true,再判断后者,否则就直接 false 。
其实不推荐这种写法,本身这个写法其实很易懂了,楼主还是没直接理解。 这种东西拜托不要写在业务代码里。 |
25
dremy 2020-06-23 13:08:41 +08:00
@Vogan
@taxiaohaohhh 见 https://eslint.org/docs/rules/no-unused-expressions Expected an assignment or function call and instead saw an expression. |
26
nianyu 2020-06-23 13:15:18 +08:00
如果存在 fn 就执行 fn, 正常业务代码这么写的比较少
|
27
xiangyuecn 2020-06-23 13:18:31 +08:00
@nianyu 就算你不手写,打包后人家自动帮你改成这个格式😏
源码:function aa(fn){ if(fn)fn() } UglifyJS ( webpack ) 压缩:function aa(t){t&&t()} |
28
no1xsyzy 2020-06-23 13:22:19 +08:00
@dremy #25 首先,你搞错了,这个问题不是 no-unused-expressions 。
其次,eslint 是可配置的。 |
29
ChanKc 2020-06-23 13:22:46 +08:00 via Android 1
果然出现了
js 一大争议:是否手动 minify 根源上是“程序主要是给人读的”还是“程序主要是给机器读的”的争议 |
30
nannanziyu 2020-06-23 13:23:08 +08:00
|
31
ChanKc 2020-06-23 13:25:33 +08:00 via Android
换我我就写 typeof fn === 'function'
|
32
lemon6 2020-06-23 13:27:27 +08:00 via Android
短路写法啊,减少代码量,而且就这么一点东西哪有降低可读性一说?
|
33
zhuweiyou 2020-06-23 13:29:53 +08:00 1
这样写是错误的,应该 typeof fn === "function"
|
34
marcong95 2020-06-23 13:30:23 +08:00 1
@dremy #25 这只是 ESLint 的一个规则,并不代表这种写法不被提倡,何况你这个规则也并不在 eslint:recommended 里面
JS 里面大量需要判断函数非空,要是都 if 一下只会把代码弄得又长又臭 |
36
binux 2020-06-23 13:31:26 +08:00 via Android
@nannanziyu #29 你还得判断它是不是一个异步函数,再捕获它的异常。
|
37
ChanKc 2020-06-23 13:34:16 +08:00
真要减少代码量就上 ts
这检查还检查得不彻底 |
39
lizz666 2020-06-23 13:45:24 +08:00
你未来还会看到类似 window?.fb?.() 的
|
40
belin520 2020-06-23 13:47:20 +08:00
这样写思路是对的,实现是错误的,fn 可能存在,但是它可能不是 function,执行 fn() 一样会出错。
typeof fn === "function" && fn() |
41
taxiaohaohhh 2020-06-23 13:47:25 +08:00
@nannanziyu
就我回复的层主,{fn ? fn(abc) : null},你要讲没判断是否是函数负分,if 能加难道我这个加不了? |
42
ChanKc 2020-06-23 13:49:38 +08:00 1
用一个很流行的词来说这个代码:心智负担
要彻底看懂这个代码,需要 1 完全记住 js 的自动类型转换规则 2 记住 0, NaN, null, undefined, ''是 falsy 的值,其它都是 truthy 的 而且以上两条基本要靠死记硬背,没什么规律可言 基本上偏学术性的编程书都不推荐这个写法 偏工程的就有一些推荐的,原因就只有减少代码量 |
43
marcong95 2020-06-23 13:50:29 +08:00
@dremy #38 那么问题来了,单纯的 fn() 是语句呢,还是表达式呢?那说 new Vue({ ... }) 呢
|
44
Marstin 2020-06-23 13:51:27 +08:00
如果按照楼上的众多反对说法,三元表达式和 lambda 表达式都应该取缔。
避免因程序报错中断因而影响后续逻辑的继续执行,这种短路用法不是很实用吗 |
45
starcraft 2020-06-23 13:54:13 +08:00 via iPhone
哈哈哈 还有人说这是装笔的。这是对得不能再对的做法了。果真无知才是最装笔的。评论区依旧没让人失望。
|
46
slxyzzl 2020-06-23 14:06:45 +08:00
我想问业务代码这么写有什么问题,老项目我们全是这样写的,新项目换成可选链了
|
47
ypzhou 2020-06-23 14:06:58 +08:00 1
fn?.()
|
48
lscho 2020-06-23 14:09:16 +08:00 8
难道我这么多年 js 白写了吗?这难道不是回调函数时正常的写法?
也不需要 typeof fn === "function" 判断,因为期望参数 fn 是函数,如果不是,那就应该抛出异常。 |
49
no1xsyzy 2020-06-23 14:10:55 +08:00
@dremy #25 又翻了一下只看到 no-unneeded-ternary 里面 Good 例子用到了 bar || 1
而 fn && fn() 是 lint-free 的,即使钩上所有 rule ( ES2016 + browser ) 大概需要避免 fn && fn() 需要自己写扩展 document.write(((fn) => { "use strict"; return fn && fn(); })()); |
51
IGJacklove 2020-06-23 14:16:12 +08:00 via Android
@dremy 也不会把,现在 ts 都有?. 和??各种操作了,要是都 if 判空不得累死你?
|
53
xcatliu 2020-06-23 14:42:59 +08:00 1
@dremy 你怕是没读过 React 官方文档吧。React 的标准写法分明是 <div>fn && fn(abc)</div>
https://reactjs.org/docs/conditional-rendering.html#inline-if-with-logical--operator |
55
whileFalse 2020-06-23 15:06:08 +08:00
@dremy 这种写法出现的时候你大概还不会写程序。
|
56
Sapp 2020-06-23 15:06:09 +08:00
现在用这个:fn?.()
|
57
zhjie 2020-06-23 15:07:21 +08:00
对于 js 来说 这么写基本没有心智负担。甚至面试都会提问。
|
58
maichael 2020-06-23 15:09:20 +08:00
@ChanKc #33 上 TS 也解决不了这问题,你不能担保调用你这个函数的人也用的 TS,而且也存在 fn 可以为空的情况。
|
59
goodboy95 2020-06-23 15:12:34 +08:00
@ChanKc js 里面记住非 true 的情况感觉是基本吧,而且这个明显就是只为了回避 null 和 undefined. 这都有心智负担的话,我只能怀疑拿到代码的人以前根本就没碰过 js,临时被拉去维护 js 项目。只要是写 js 吃饭的,这种代码应该都是瞄一眼就过去的事情。
|
60
Jirajine 2020-06-23 15:13:13 +08:00 via Android
这个就是 js 逻辑运算符的魔法:
当多个 &&串联时,执行到第一个 truthy 的表达式; 当多个||串联时,执行到第一个 false-thy 的表达式; 但我比较赞同王垠博客上的观点:短路机制是给程序优化执行效率的,不是给程序员拿来炫技的。 |
61
ChanKc 2020-06-23 15:14:16 +08:00 via Android
@maichael 如果是完全内部使用的函数,ts 可以解决问题。我刚刚在 playground 上试了一下,指定 fn 为 Function 类型,如果 fn 是空就会编译错误。如果是对外的函数,这个判断也需要假设用户传入的要么是 falsy 的值要么是函数。那么为什么不干脆假设用户传入的就是个函数?
|
62
maichael 2020-06-23 15:18:25 +08:00
@ChanKc #57 因为你没法这么假设,需求完全可能是 fn 的类型是 Function | undefined,这是需求层面决定的,传了我就执行,不传我就不执行,这是很正常的需求。
|
63
ChanKc 2020-06-23 15:18:49 +08:00 via Android
@goodboy95 Cay S Horstman 就觉得这个不是基本的。Douglas Crockford 也建议“Use booleans in all conditions”
|
64
ChanKc 2020-06-23 15:20:21 +08:00 via Android
@maichael 如果需求是这样,显式的===undefined 然后让 minifier 去 minify 不好吗
|
65
ChanKc 2020-06-23 15:25:37 +08:00 via Android
@goodboy95 要达到你这个要求,你就要在招聘的时候让每个应聘者背出 falsy 的值,确保不会有别的团队写 c 的写 java 的调岗到你的团队,然后你才可以放心地使用各种 truthy 和 falsy 的 hack 而保证不出错
|
66
no1xsyzy 2020-06-23 15:47:28 +08:00
|
67
bojackhorseman 2020-06-23 15:49:36 +08:00
这也能吵起来。。。
|
68
ChanKc 2020-06-23 15:55:31 +08:00 via Android
@no1xsyzy 我当然猜得到,问题根本不在短路,而是在强制类型转换。JS 的强制类型转换规则对别的语言的程序员来说是很奇葩的
|
69
no1xsyzy 2020-06-23 16:00:49 +08:00
@ChanKc #68 慢点这里没有强制类型转换啊,你说的是隐式类型转换的话,Python 、C 、Java 等等一大堆都有任何东西当作布尔的倾向,以至于 codegolf meta 那边专门提出 “如果要返回 True/False 的话 Truthy 和 Falsy 是否可以直接用”,最后提出能塞进分支判断直接当 True/False 用的都算(因为是 Code Golf 所以需要进行社区约定)
自然,三位一体本身倒是让人难受,但 T/F 我觉得还不至于,总比 't 和 nil 是标准形态好多了。 |
71
Jirajine 2020-06-23 16:07:58 +08:00 via Android
@no1xsyzy 没有反,&&遇到 true 就短路所以是执行到第一个 truethy 的表达式后停止,当然这里说执行不准确应该是 evaluate 。
不是我秀英文,这个词我中文表示出来。而且这俩本来就是词典里没有的生造词,忘了别人怎么写的了我就随手打出来,能表达清意思就够了,论坛回帖又不是写论文,何必咬文嚼字。 |
73
DOLLOR 2020-06-23 16:25:58 +08:00 2
请用最新写法 [fn?.()] ,更简单易读,其他的都别争了,省点口水吧。
|
76
DOLLOR 2020-06-23 16:51:29 +08:00
@progerchai
就是?.操作符,不包括方括号,我把引号打成方括号了。 可以参见这里: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining |
77
ke1vin 2020-06-23 17:27:04 +08:00
不用判断类型?
|
80
no1xsyzy 2020-06-23 18:07:51 +08:00
@Jirajine #71 提问:
1 && 2 && 3 && 4 = ? null || undefined || 0 || "" = ? && 是遇到 false 短路啊,遇到 true 继续,不然怎么是 if(a){b} 呢 |
82
iamppz 2020-06-23 19:19:57 +08:00 via iPhone
js 不这么写,ts 会这么写,因为类型检查有编译器处理
|
84
Jirajine 2020-06-23 20:05:13 +08:00
@no1xsyzy #80 好吧是我弄反了,自己印证了上面的观点:尽量避免这么用。
回帖搞反顶多被网友批判一番,关键业务逻辑搞反造成重大损失可能就得跑路了。 |
86
auroraccc 2020-06-23 20:28:01 +08:00
a && a.b && a.b.c && a.b.c()
a?.b?.c |
87
cigarzh 2020-06-23 21:48:12 +08:00
函数式编程基操
不要用面向对象的思想思考函数式编程的玩意… |
88
royzxq 2020-06-24 00:10:11 +08:00
偷懒的时候会这么写
|
89
back0893 2020-06-24 00:15:31 +08:00
有 fn 就执行
灭有就不执行 不是很常规的写法 |
91
fuwu1245 2020-06-24 10:08:04 +08:00
如果 fn 不是函数呢?那 fn()不就是个错了么
|
92
donghui1993 2020-07-28 14:00:56 +08:00
正确写法应该时这个吧:typeof(fn)==='function' && fn(),不过通常约定 fn&&fn() 传递的一定是函数
|