javascript 如何缩短我的条件语句
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18347033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to shorten my conditional statements
提问by FlyingCat
I have a very long conditional statement like the following:
我有一个很长的条件语句,如下所示:
if(test.type == 'itema' || test.type == 'itemb' || test.type == 'itemc' || test.type == 'itemd'){
// do something.
}
I was wondering if I could refactor this expression/statement into a more concise form.
我想知道是否可以将此表达式/语句重构为更简洁的形式。
Any idea on how to achieve this?
关于如何实现这一目标的任何想法?
回答by Yuriy Galanter
You can use switch statement with fall thru:
您可以使用带有 fall thru 的 switch 语句:
switch (test.type) {
case "itema":
case "itemb":
case "itemc":
case "itemd":
// do something
}
回答by Joseph Silber
Put your values into an array, and check if your item is in the array:
将您的值放入一个数组中,并检查您的项目是否在数组中:
if ([1, 2, 3, 4].includes(test.type)) {
// Do something
}
If a browser you support doesn't have the Array#includes
method, you can use this polyfill.
如果您支持的浏览器没有该Array#includes
方法,您可以使用这个 polyfill。
Short explanation of the ~
tilde shortcut:
~
波浪号快捷方式的简短说明:
Update:Since we now have the
includes
method, there's no point in using the~
hack anymore. Just keeping this here for people that are interested in knowing how it works and/or have encountered it in other's code.
更新:既然我们现在有了这个
includes
方法,就没有必要~
再使用hack 了。只是将它保留在这里,供那些有兴趣了解它是如何工作的和/或在其他代码中遇到过它的人使用。
Instead of checking if the result of indexOf
is >= 0
, there is a nice little shortcut:
除了检查indexOf
is的结果之外>= 0
,还有一个不错的小捷径:
if ( ~[1, 2, 3, 4].indexOf(test.type) ) {
// Do something
}
Here is the fiddle: http://jsfiddle.net/HYJvK/
这是小提琴:http: //jsfiddle.net/HYJvK/
How does this work? If an item is found in the array, indexOf
returns its index. If the item was not found, it'll return -1
. Without getting into too much detail, the ~
is a bitwise NOT operator, which will return 0
only for -1
.
这是如何运作的?如果在数组中找到一项,则indexOf
返回其索引。如果未找到该项目,它将返回-1
。在不涉及太多细节的情况下, the~
是一个按位非运算符,它将0
仅返回for -1
。
I like using the ~
shortcut, since it's more succinct than doing a comparison on the return value. I wish JavaScript would have an in_array
function that returns a Boolean directly (similar to PHP), but that's just wishful thinking (Update:it now does. It's called includes
. See above). Note that jQuery's inArray
, while sharing PHP's method signature, actually mimics the native indexOf
functionality (which is useful in different cases, if the index is what you're truly after).
我喜欢使用~
快捷方式,因为它比对返回值进行比较更简洁。我希望 JavaScript 有一个in_array
直接返回布尔值的函数(类似于 PHP),但这只是一厢情愿的想法(更新:现在有了。它被称为includes
。见上文)。请注意 jQuery 的inArray
,虽然共享 PHP 的方法签名,但实际上模仿了本机indexOf
功能(这在不同情况下很有用,如果索引是您真正想要的)。
Important note:Using the tilde shortcut seems to be swathed in controversy, as some vehementlybelieve that the code is not clear enough and should be avoided at all costs (see the comments on this answer). If you share their sentiment, you should stick to the .indexOf(...) >= 0
solution.
重要说明:使用波浪号快捷方式似乎充满争议,因为有些人强烈认为代码不够清晰,应该不惜一切代价避免使用(请参阅对此答案的评论)。如果你同意他们的观点,你应该坚持.indexOf(...) >= 0
解决方案。
A little longer explanation:
稍微长一点的解释:
Integers in JavaScript are signed, which means that the left-most bit is reserved as the sign bit; a flag to indicate whether the number is positive or negative, with a 1
being negative.
JavaScript 中的整数是有符号的,这意味着最左边的位被保留为符号位;指示数字是正数还是负数的标志,a1
为负数。
Here are some sample positive numbers in 32-bit binary format:
以下是一些 32 位二进制格式的示例正数:
1 : 00000000000000000000000000000001
2 : 00000000000000000000000000000010
3 : 00000000000000000000000000000011
15: 00000000000000000000000000001111
Now here are those same numbers, but negative:
现在这里是相同的数字,但为负数:
-1 : 11111111111111111111111111111111
-2 : 11111111111111111111111111111110
-3 : 11111111111111111111111111111101
-15: 11111111111111111111111111110001
Why such weird combinations for the negative numbers? Simple. A negative number is simply the inverse of the positive number + 1; adding the negative number to the positive number should always yield 0
.
为什么负数的组合如此奇怪?简单的。负数只是正数 + 1 的倒数;将负数添加到正数应该总是 yield 0
。
To understand this, let's do some simple binary arithmetic.
为了理解这一点,让我们做一些简单的二进制算术。
Here is how we would add -1
to +1
:
以下是我们将如何添加-1
到+1
:
00000000000000000000000000000001 +1
+ 11111111111111111111111111111111 -1
-------------------------------------------
= 00000000000000000000000000000000 0
And here is how we would add -15
to +15
:
这是我们将如何添加-15
到+15
:
00000000000000000000000000001111 +15
+ 11111111111111111111111111110001 -15
--------------------------------------------
= 00000000000000000000000000000000 0
How do we get those results? By doing regular addition, the way we were taught in school: you start at the right-most column, and you add up all the rows. If the sum is greater than the greatest single-digit number (which in decimal is 9
, but in binary is 1
) we carry the remainder over to the next column.
我们如何得到这些结果?通过定期加法,我们在学校教的方式:你从最右边的列开始,然后把所有的行加起来。如果总和大于最大的一位数(十进制为9
,二进制为1
),我们将余数转移到下一列。
Now, as you'll notice, when adding a negative number to its positive number, the right-most column that is not all 0
s will always have two 1
s, which when added together will result in 2
. The binary representation of two being 10
, we carry the 1
to the next column, and put a 0
for the result in the first column. All other columns to the left have only one row with a 1
, so the 1
carried over from the previous column will again add up to 2
, which will then carry over... This process repeats itself till we get to the left-most column, where the 1
to be carried over has nowhere to go, so it overflows and gets lost, and we're left with 0
s all across.
现在,您会注意到,当将负数与正数相加时,并非全为0
s的最右侧列将始终有两个1
s,将它们加在一起将导致2
. 两个是 的二进制表示10
,我们将1
带到下一列,并将0
结果放在第一列中。左边的所有其他列只有一行带有 a 1
,因此1
从前一列结转的值将再次加起来为2
,然后结转......这个过程会不断重复,直到我们到达最左边的列,其中在1
被结转无处可去,所以它溢出和丢失,我们就只剩下0
一切都跨越。
This system is called 2's Complement. You can read more about this here:
这个系统被称为2的补码。您可以在此处阅读有关此内容的更多信息:
2's Complement Representation for Signed Integers.
Now that the crash course in 2's complement is over, you'll notice that -1
is the only number whose binary representation is 1
's all across.
既然 2 的补码的速成课程已经结束,您会注意到这-1
是唯一一个二进制表示为1
's all的数字。
Using the ~
bitwise NOT operator, all the bits in a given number are inverted. The only way to get 0
back from inverting all the bits is if we started out with 1
's all across.
使用~
按位非运算符,给定数字中的所有位都被反转。0
从反转所有位回来的唯一方法是,如果我们从1
's allcross 开始。
So, all this was a long-winded way of saying that ~n
will only return 0
if n
is -1
.
所以,所有这些都是一种冗长的说法,~n
只有0
在n
is时才会返回-1
。
回答by Muhammad Umer
Using Science: you should do what idfah said and this for fastest speed while keep code short:
使用科学:你应该按照 idfah 所说的去做,这样可以在保持代码简短的同时获得最快的速度:
THIS IS FASTER THAN ~
Method
这比~
方法更快
var x = test.type;
if (x == 'itema' ||
x == 'itemb' ||
x == 'itemc' ||
x == 'itemd') {
//do something
}
http://jsperf.com/if-statements-test-techsin(Top set: Chrome, bottom set: Firefox)
http://jsperf.com/if-statements-test-techsin(上集:Chrome,下集:Firefox)
Conclusion :
结论 :
Ifpossibilities are fewand you know that certain ones are more likely to occur than you get maximum performance out if ||
,switch fall through
, and if(obj[keyval])
.
如果可能性是少数,你知道,某些是更有可能比你得到最大的性能出去发生if ||
,switch fall through
和if(obj[keyval])
。
Ifpossibilities are many, and anyone of them could be the most occurring one, in other words, you can't know that which one is most likely to occur than you get most performance out of object lookup if(obj[keyval])
and regex
if that fits.
如果可能性有很多,并且其中任何一个都可能是最常发生的,换句话说,您无法知道哪一个最有可能发生,而不是从对象查找中获得最大的性能if(obj[keyval])
以及regex
是否合适。
http://jsperf.com/if-statements-test-techsin/12
http://jsperf.com/if-statements-test-techsin/12
i'll update if something new comes up.
如果有新东西出现,我会更新。
回答by idfah
If you are comparing to strings and there is a pattern, consider using regular expressions.
如果您要与字符串进行比较并且存在模式,请考虑使用正则表达式。
Otherwise, I suspect attempting to shorten it will just obfuscate your code. Consider simply wrapping the lines to make it pretty.
否则,我怀疑试图缩短它只会混淆你的代码。考虑简单地包裹线条以使其漂亮。
if (test.type == 'itema' ||
test.type == 'itemb' ||
test.type == 'itemc' ||
test.type == 'itemd') {
do something.
}
回答by kojiro
var possibilities = {
"itema": 1,
"itemb": 1,
"itemc": 1,
…};
if (test.type in possibilities) { … }
Using an object as an associative array is a pretty common thing, but since JavaScript doesn't have a native set you can use objects as cheap sets as well.
使用对象作为关联数组是很常见的事情,但由于 JavaScript 没有本地集,您也可以将对象用作廉价集。
回答by Matt
if( /^item[a-d]$/.test(test.type) ) { /* do something */ }
or if the items are not that uniform, then:
或者如果物品不是那么统一,那么:
if( /^(itema|itemb|itemc|itemd)$/.test(test.type) ) { /* do something */ }
回答by Fran Hoey
Excellent answers, but you could make the code far more readable by wrapping one of them in a function.
很好的答案,但是您可以通过将其中之一包装在一个函数中来使代码更具可读性。
This is complex if statement, when you (or someone else) read the code in a years time, you will be scanning through to find the section to understand what is happening. A statement with this level of business logic will cause you to stumble for a few seconds at while you work out what you are testing. Where as code like this, will allow you to continue scanning.
这是一个复杂的 if 语句,当您(或其他人)在几年后阅读代码时,您将浏览以找到该部分以了解正在发生的事情。具有这种业务逻辑级别的语句会导致您在计算正在测试的内容时绊倒几秒钟。像这样的代码,将允许您继续扫描。
if(CheckIfBusinessRuleIsTrue())
{
//Do Something
}
function CheckIfBusinessRuleIsTrue()
{
return (the best solution from previous posts here);
}
Name your function explicitly so it immediately obvious what you are testing and your code will be much easier to scan and understand.
明确命名您的函数,以便您立即了解您正在测试的内容,并且您的代码将更易于扫描和理解。
回答by Guido Anselmi
You could put all the answers into a Javascript Setand then just call .contains()
on the set.
您可以将所有答案放入一个Javascript 集合中,然后调用.contains()
该集合。
You still have to declare all the contents, but the inline call will be shorter.
您仍然需要声明所有内容,但内联调用会更短。
Something like:
就像是:
var itemSet = new Set(["itema","itemb","itemc","itemd"]);
if( itemSet.contains( test.type ){}
回答by zaph
For readability create a function for the test (yes, a one line function):
为了可读性,为测试创建一个函数(是的,一个单行函数):
function isTypeDefined(test) {
return test.type == 'itema' ||
test.type == 'itemb' ||
test.type == 'itemc' ||
test.type == 'itemd';
}
then call it:
然后调用它:
…
if (isTypeDefined(test)) {
…
}
...
回答by Muhammad Umer
another way or another awesome way i found is this...
我发现的另一种方式或另一种很棒的方式是这样的......
if ('a' in oc(['a','b','c'])) { //dosomething }
function oc(a)
{
var o = {};
for(var i=0;i<a.length;i++) o[a[i]]='';
return o;
}
of course as you can see this takes things one step further and make them easy follow logic.
当然,正如您所看到的,这使事情更进一步,并使它们易于遵循逻辑。
http://snook.ca/archives/javascript/testing_for_a_v
http://snook.ca/archives/javascript/testing_for_a_v
using operators such as ~ && || ((),()) ~~ is fine only if your code breaks later on. You won't know where to start. So readability is BIG.
使用诸如 ~ && || 之类的运算符 ((),()) ~~ 只有当您的代码稍后中断时才可以。你会不知道从哪里开始。所以可读性很重要。
if you must you could make it shorter.
如果你必须,你可以缩短它。
('a' in oc(['a','b','c'])) && statement;
('a' in oc(['a','b','c'])) && (statements,statements);
('a' in oc(['a','b','c']))?statement:elseStatement;
('a' in oc(['a','b','c']))?(statements,statements):(elseStatements,elseStatements);
and if you want to do inverse
如果你想做逆
('a' in oc(['a','b','c'])) || statement;