如下:
if(true) return
if(true) name = 'xxx'
if(true) name.push({name1})
name.forEach(v => v.name === name && name.push(v))
name && this.$set(this,'name', 'haha')
interval && clearInterval(interval)
这样子写会有什么隐藏的风险吗?
希望大家能帮忙解惑,还有欢迎分享你们觉得方便快捷的写法。谢谢!
这种写法是为了避免 undefined
/null
,也就是其他语言中的空指针异常。
这种利用布尔短路来做的,本质是利用 Truthy;但如果你只是单纯的需要防止非空,那么可能会有潜在的问题。
比如:
let person = { 'name': '张三' };
let firstName = person && person.name && person.name.substr && person.name.substr(0, 1) || '匿名';
上面这种写法乍一看没问题,但如果 person.name
是空字符串 ''
,也会被当做布尔值 false
;如果某些情况下确实空字符串也要正常处理输出空字符串、而不是输出“匿名”,就出现逻辑错误。
再比如某个函数内传入配置项,如果未传入则使用默认值:
function delay(timeout) {
timeout = timeout || 30;
}
delay(); // timeout: 30
看上去完美的处理了,但某些情况下 timeout
就是要传 0
这个值,但也因为 Truthy 的问题而出现了逻辑错误。
正确的写法应该是:
let firstName = (person !== null && person !== undefined) && (person.name !== null && person.name !== undefined) && (person.name.substr !== null && person.name.substr !== undefined) ?
person.name.substr(0, 1) :
'无名';
function delay(timeout) {
timeout = (timeout !== null && timeout !== undefined) ? timeout : 30;
}
但显然写法上很啰嗦,ES 也注意到了这个问题,在微软主导的 TS 的推动下,吸收了 C# 等语言的优秀语法糖:非空断言操作符和可选链操作符。
let firstName = person?.name?.substr(0, 1) ?? '匿名';
function delay(timeout) {
timeout = timeout ?? 30;
}
不过出于兼容性考虑,低版本环境还需 babel 等工具做转译。
如果你的业务场景不需要考虑上述这种 Truthy(并不是真·True)带来的问题,那么简写也无妨。
###最大的风险就是代码不好读:)
###挺好 没啥问题。
至于可读性,并不影响,我觉得反而容易让看的人花很少的时间学习到知识。
这样写对新手不友好
###简写感觉牛逼,但增加了阅读难度,webpack工具打包后会处理成你上面的情况,人写代码,还是老实点