在if语句中的布尔值


144

今天,我考虑到我在学校作业中检查变量是对还是错的方式,对代码进行了评论。

我写的代码是这样的:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

他们说最好这样写:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

我对“ === true”部分的评论是,它不是必需的,并且可能引起混乱。

但是我的想法是,最好检查变量是否为布尔值,尤其是因为Javascript是一种松散类型的语言。

在第二个示例中,字符串也将返回“ something”。

所以我的问题;将来松散“ === true”部分是否更整洁,还是检查变量类型的好习惯?

编辑: 在我的“真实”代码中,布尔值表示是否已删除图像,因此boolValue唯一应具有的值是true或false。

例如,0和1不应在该变量中。


4
它是可读的,很好的做法,使用===
Piyas德

2
为+1 === true。避免混乱!
gashu 2013年

1
@gashu考虑[0] === true评估为假。
RestingRobot 2013年

1
@Jlange不应该吗?请解释
gashu 2013年

我的意思是,如果您只是想检查“真实的”存在,则该语句将失败,即使该语句的求值结果为true([0]的求值结果为true,但没有类型转换也不行)。这实际上取决于您要用语句完成的工作。使用=== true时,您需要确保该条件正好等于true
RestingRobot 2013年

Answers:


222

首先,事实是:

if (booleanValue)

if对于任何真实值(booleanValue包括true,任何非零数字,任何非空字符串值,任何对象或数组引用等),将满足该语句。

另一方面:

if (booleanValue === true)

if如果booleanValue正好等于,这将满足条件true。没有其他真实的价值能够满足它。

另一方面,如果您这样做:

if (someVar == true)

然后,Javascript将要做的是键入强制类型true以匹配的类型,someVar然后比较两个变量。在很多情况下,这可能不是人们想要的。因此,在大多数情况下,您都想避免使用,==因为关于Java语言如何强制将两种类型的内容强制转换为同一类型的规则很长,除非您了解所有这些规则并且可以预期JS解释器在何时执行的所有操作给定两种不同的类型(大多数JS开发人员无法做到),您可能希望==完全避免。

作为一个令人困惑的例子:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

对于值2,您会认为这2是一个真实值,因此可以与相比,这是正确的值true,但这不是类型强制的工作原理。它正在转换右手值以匹配左手值的类型,因此将其转换true为数字,1以便进行比较2 == 1,这肯定不是您可能想要的。

因此,买家要当心。==除非您明确知道要比较的类型,并且知道所有可能的类型强制算法如何工作,否则最好避免在几乎所有情况下使用。


因此,它实际上取决于期望值booleanValue以及您希望代码如何工作。如果您事先知道它只会有一个truefalse值,则将其与

if (booleanValue === true)

只是多余的代码,是不必要的,

if (booleanValue)

更紧凑,可以说更清洁/更好。

另一方面,如果您不知道booleanValue可能是什么,并且想要测试是否将其设置为true true且不允许其他自动类型转换,则

if (booleanValue === true)

不仅是一个好主意,而且是必需的。


例如,如果您查看.on()jQuery 中的实现,则它具有可选的返回值。如果回调返回false,则jQuery将自动停止事件的传播。在这种特定情况下,由于jQuery只希望停止false返回时的传播,因此他们明确地检查返回值,=== false因为他们不希望undefinedor 0""or或其他任何将自动类型转换为false的内容也可以满足比较。

例如,这是jQuery事件处理回调代码:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

您可以看到jQuery正在明确寻找ret === false

但是,考虑到代码的需求,jQuery代码中还有许多其他地方需要进行更简单的检查。例如:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...

我已经思考这个问题已有一段时间了,但是还没有机会找到任何人问。如果您可以看一下,我将不胜感激。stackoverflow.com/questions/32615466/…–
mmm

这个答案不是完全正确的。'x == true'对于非零数字将为true。
Teemoh

@Teemoh-我不明白您的评论。参见jsfiddle.net/jfriend00/89h8d8tm
jfriend00

1
我只想说'if(x)'与'if(x == true)'不同,就像您在答案的第一段中所写的那样。'if(x)'将显式地将'x'转换为其布尔表示形式。'if(x == true)'将使用EcmaScript抽象比较算法。您写道,“ if(x == true)”对于任何非零数字或非空字符串或任何对象都为true。这是错误的。如果我用2而不是1来运行您的示例,它将无法正常工作。
Teemoh

2
@Teemoh-我明白你的意思了。答案已得到纠正和澄清,我在示例中添加了有关强制类型的部分,并举例说明了它如何执行意外的操作。
jfriend00

40

如果您写:if(x === true),则只有x = true才成立

如果您输入:if(x),则对于任何非x都将为true ”(空字符串),false,null,undefined,0,NaN。


(空字符串),false,null,未定义,0,NaN
Oliboy50

不要忘记NaN-0
haykam

8

在简单的“如果”中,变量将强制为布尔值,并且在对象上使用toBoolean:

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, 0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

但是与===的比较没有任何类型强制,因此它们必须相等而没有强制。

如果您说该对象甚至可能不是布尔值,那么您可能不仅要考虑true / false。

if(x===true){
...
} else if(x===false){
....
} else {
....
}

5

这取决于您的用例。检查类型也可能很有意义,但是如果只是一个标志,则不是。


===比较不执行强制类型转换。因此,OP的代码有效地测试了标志的类型。仅当值是布尔值且为true时,它才会成功。
杰西·哈雷特

让我改一下。如果您知道它是对还是错,那就没关系。
2013年

5

通常,省略会更干净,更简单=== true

但是,在Javascript中,这些语句是不同的。

if (booleanValue)如果将执行booleanValuetruthy -比其他任何东西0false''NaNnull,和undefined

if (booleanValue === true)仅在booleanValue精确等于时执行true


即使当我只希望boolValue为true或false时,这正是我想要确定的。该变量在代码中多次设置为true / false。我知道在编写代码时,但是如果一年后再次检查代码,那么除非我重新阅读所有内容,否则它只是一个很大的问号?
DirkZz 2013年

@aldanux:糟糕!我是说''
SLaks's

4

身份(===)运算符的行为与相等(==)运算符的行为相同,只是不进行类型转换,并且类型必须相同才能被视为相等。


您的最后一句话是错误的。尝试两个语句if (booleanValue)if (booleanValue==true)何时booleanValue2。这两个语句不会给您相同的结果。
jfriend00

有趣。你的话我记住了。我想在ObjC / C / C ++世界中,在JS中,我假设您是正确的,因为JS中的数据类型可以更改,并且2 == true不能量化if if。
阿波罗软件

1
有关此特定示例,请参见上面的答案。它与Javascript如何进行自动类型转换有关,以便比较两个不同类型的值。
jfriend00 '19

3

由于检查的值是Boolean首选,因此最好直接使用它以减少编码,并且完全相同==true


2

由于您已经明确将其初始化为bool,因此我认为===不需要运算符。


2

如果该变量只能使用布尔值,那么使用较短的语法是合理的。

如果它可能被分配其他类型,并且需要区分true来自1或者"foo",则必须使用=== true


2

我认为您的推理是正确的。但实际上,我发现省略===比较是很常见的。我认为有以下三个原因:

  1. 它通常不会增加表达式的含义-在已知该值仍然是布尔值的情况下。
  2. 由于JavaScript中存在大量类型不确定性,因此当您获得意外undefinednull有价值的信息时,强制进行类型检查会咬住您。在这种情况下,通常您只是希望测试失败。(尽管我试图用“快速失败”的座右铭来平衡这一观点)。
  3. JavaScript程序员喜欢快速轻松地使用类型,特别是在布尔表达式中,因为我们可以。

考虑以下示例:

var someString = getInput();
var normalized = someString && trim(someString);  
// trim() removes leading and trailing whitespace

if (normalized) {
    submitInput(normalized);
}

我认为这种代码并不罕见。它处理情况getInput()回报undefinednull或一个空字符串。由于有两个布尔值,submitInput()因此仅当给定输入为包含非空格字符的字符串时才调用布尔求值。

在JavaScript中,&&如果第一个参数为假,则返回其第一个参数;如果第一个参数为真,则返回第二个参数。如果未定义,normalized也会如此,依此类推。这意味着上述布尔表达式的输入实际上都不是布尔值。undefinedsomeString

我知道很多程序员在看到这样的代码时习惯于强大的类型检查能力。但是请注意,应用强类型键入可能需要显式检查nullundefined值,这会使代码混乱。在JavaScript中不需要。


1

这取决于。如果您担心变量最终可能会变成TRUE。然后必须进行严格检查。否则由您决定。但是,我怀疑该语法whatever == TRUE是否会混淆任何知道自己在做什么的人。


1

在Javascript中,布尔值的概念很模糊。考虑一下:

 var bool = 0 
 if(bool){..} //evaluates to false

 if(//uninitialized var) //evaluates to false

因此,当您使用if语句(或任何其他控制语句)时,不必使用“布尔”类型var。因此,我认为,如果您知道语句是布尔值,则语句的“ === true”部分是不必要的,但如果您的值是模棱两可的“真实”变量,则绝对必要。可以在javscript中找到有关布尔值的更多信息



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.