在数组的.find方法中使用三元制时,我遇到了一些令人困惑的行为。当搜索对象时:
考虑一下:
const list = [
{ id: 1, name: "dave"},
{ id: 3, name: "choi"},
{id: 4, name: "bob"}
]
// this works
let isBoy = true
console.log(list.find(v => v.name === isBoy ? "dave" : "choi"))
// this don't work
isBoy = false
console.log(list.find(v => v.name === isBoy ? "dave" : "choi"))
// this always works: use () around ternary
console.log(list.find(v => v.name === (isBoy ? "dave" : "choi")))
isBoy = true
console.log(list.find(v => v.name === (isBoy ? "dave" : "choi")))
让我惊讶的是
// this don't work
isBoy = false
console.log(list.find(v => v.name === isBoy ? "dave" : "choi"))
它将返回"dave"
而不是"choi"
。这就是一个现在很难发现的bug的原因。谁能解释这是怎么回事,为什么这是预期行为?
为什么括号很重要?为了更好地理解这一点,我应该读些什么?这是操作顺序的问题吗?我的javascript IDE过滤器没有抱怨或警告这个,它通常在模糊的操作顺序的东西。
我尝试了什么
我试着搜索SA类似的问题,可能会对这个问题有所帮助,但没有找到任何解释我所看到的。
问题是操作符优先级。比较运算符的优先级比三元运算符高(因为通常在条件中使用比较),因此您的代码被解释为:
list.find(v => (v.name === isBoy) ? "dave" : "choi")
你需要添加括号来得到你想要的:
list.find(v => v.name === (isBoy ? "dave" : "choi"))
嗯,
你是对的,这是因为javascript执行的顺序,
v.name === isBoy ? "dave" : "choi")
相当于
if ( v.name === isBoy ) {
return "dave"
} else {
return "choi"
}
部分问题是.find()
内部的函数需要返回布尔值。您的前两个示例不返回布尔值-它们返回'dave'
或'choi'
而不是true
或false
。然后,计算机将输出解释为真,并且.find()
查询将始终返回列表的第一个值。将代码更改为console.log(list.find(v => v.name === (isBoy ? "dave" : "choi")))
工作是因为.find()
内部的函数总是返回一个布尔值——如果isBoy===true
,它将返回v.name==="dave"
,如果不是,它将返回v.name==="choi"
。