Javascript 有点痛苦的三重嵌套三值运算符
我浏览了Raphael.js的源代码,了解他是如何将RGB值转换为HSB的。我发现了他使用的函数,当时我正在将其转换为Python,这时我遇到了这个漂亮的三重嵌套三值运算符:Javascript 有点痛苦的三重嵌套三值运算符,javascript,if-statement,ternary-operator,Javascript,If Statement,Ternary Operator,我浏览了Raphael.js的源代码,了解他是如何将RGB值转换为HSB的。我发现了他使用的函数,当时我正在将其转换为Python,这时我遇到了这个漂亮的三重嵌套三值运算符: H = (C == 0 ? null : V == r ? (g - b) / C : V == g ? (b - r) / C + 2 : (r - g) / C + 4 ); 这让我陷入了一个循环,因为Python没有Javascript那样的三元运算符。我花了一段时
H = (C == 0 ? null :
V == r ? (g - b) / C :
V == g ? (b - r) / C + 2 :
(r - g) / C + 4
);
这让我陷入了一个循环,因为Python没有Javascript那样的三元运算符。我花了一段时间查看它,最终从中散列出了这段稍微理智一些的代码(仅使用if/else):
if (C == 0) {
H = null;
} else {
if(V == r) {
H = (g - b) / C;
} else {
if(V == g) {
H = (b - r) / C + 2;
} else {
H = (r - g) / C + 4;
}
}
}
我的解释正确吗?我之所以问这个问题,是因为如果它不正确,我将面临大量调试。所以我“明白”了吗?我想你可以用这个来避免深嵌套:
var H
if(C == 0){
H = null;
}
else if(V == r){
H = (g - b) / C;
}
else if (V == g){
H = (b - r) / C + 2;
}
else {
H = (r - g) / C + 4;
}
同样的逻辑可以用更简单的方式编写:
var H
if (C == 0)
H = null;
else if (V == r)
H = (g - b) / C;
else if (V == g)
H = (b - r) / C + 2;
else
H = (r - g) / C + 4;
可以省略大括号,因为每个条件中只有一条语句。考虑到这些条件是相互排斥的,使用else if
比嵌套if
更清晰。是的,这是正确的(除了资本化差异)。然而,它可能写得更干净,没有任何括号,可读性与elseif一样:
if (C == 0)
h = null;
else if (V == r)
h = (g - b) / C;
else if (V == g)
h = (b - r) / C + 2;
else
h = (r - g) / C + 4;
根据我个人的口味,一个仔细排列的嵌套三元组胜过if-else混乱:
const H =
C == 0 ? null :
V == r ? (g - b) / C :
V == g ? (b - r) / C + 2 :
(r - g) / C + 4 ;
我见过丹·阿布拉莫夫使用这种压痕放置模式。虽然我不喜欢条件运算符?
如何不再直观地遵循条件,但我更喜欢这一点,而不是像@lolmaus的示例,因为无论条件运算符的大小,缩进总是一致的
实际上,您开始将其视为
?
true:
false,这在这里是直观的。这样,我发现三元更容易发现和区分周围的代码。 < P>如果你的JavaScript代码库包含嵌套的三元语句,比如一个问题,考虑将格式化转换为。
他们只是在一条直线上从上到下读取,返回一个值
一旦他们遇到真实情况或撤退
你好,埃里克·埃利奥特
还有一个更优雅的想法
if (C != 0)
{
if (V == r) return (g - b) / C;
if (V == g) return (b - r) / C + 2;
return (r - g) / C + 4;
}
return null;
只需将其包装在函数中并使用,而不是如中所述的H..:
为什么不使用Python中的三元运算符
H=(
如果C==0,则为无
如果V==r,则为(g-b)/C
(b-r)/C+2如果V==g
(r-g)/C+4
)
是的,看起来你的逻辑是正确的,除了几个大写的不一致性,第一个c
atif(c==0)
应该是大写的c
,不是吗?嗯,是吗?我感觉自己就像一个被绑在背后,蒙着眼睛,对着飞镖板投飞镖的人,还射中了一个靶子。是的,@NiftyDude,没错。谢谢你的接球!看起来不错。既然您正在转换为python,我相信您不会在意这种情况,但请注意JavaScript中的==
确实存在类型强制,因此两者可能会有所不同。@dwerner:是的,确实如此。谢谢你指出这一点。很酷,谢谢。不过,我主要是在寻找逻辑验证,仅供参考。:)人们普遍认为,不使用括号所节省的空间/清洁度大大超过了对代码可维护性的危险影响。因为我将把它转换成Python,所以语法并不重要。不过还是要谢谢你!我认为python的等价物应该是elif
。。。每个人似乎都想指出的一点是避免不必要的缩进。@GGG:没错。是的。我想如果你是一个程序员,你的本能就是让任何东西都可读。。。这不能怪任何人!人们普遍认为,不使用括号所节省的空间/清洁度大大超过了对代码可维护性的危险影响@道格:几乎不会有第二次声明;此代码的唯一目的是为单个变量赋值。此外,OP正在将其转换为Python,在Python中实际上不强制使用括号:-)为什么不使用nice呢@GustvandeWal你知道这是5年前回答的,对吗?然而在webkit中嵌套一元表达式比if或switch慢60%,而在geco中则慢一点。@Zydnar,我不知道,伙计。我刚刚在Chrome控制台中运行了一个简单的基准测试,如果其他测试速度较慢:。无论使用何种变体,单个操作大约需要0.00000000 1
秒。这是一纳秒,所以你在为皮秒的差异而斗争!如果您正在按程序实时生成数据,那么这可能很重要。然而,对于绝大多数JS开发人员来说,这种差异是完全可以忽略不计的。不过,最重要的是代码可读性和开发速度。请注意,一次迭代的纳秒数包括花费在for
逻辑和=
分配上的时间。这取决于项目,如果它是一个简单的网站,你不在乎它是否是一个具有大数据的高性能项目。。。除此之外,eslint也会将嵌套的十进制标记为坏习惯,除非您将其关闭。简单的基准测试并不重要,因为有很多原因,甚至一些后台程序或插件也会影响它。好的,我的坏if-else慢,但切换比一元数和if-else快
H = (C == 0) // Is C zero?
? null // Then return `null`, else ...
: (V == r) // Is V equal to r?
? (g - b) / C // Then return this value, else ...
: (V == g) // Is V equal to g?
? (b - r) / C + 2 // Then return this value
: (r - g) / C + 4; // Otherwise fall back to this default value
if (C != 0)
{
if (V == r) return (g - b) / C;
if (V == g) return (b - r) / C + 2;
return (r - g) / C + 4;
}
return null;
function example(…) {
return condition1 ? value1
: condition2 ? value2
: condition3 ? value3
: value4;
}
// Equivalent to:
function example(…) {
if (condition1) { return value1; }
else if (condition2) { return value2; }
else if (condition3) { return value3; }
else { return value4; }
}