Logical NOT on Boolean Object在Javascript中始终返回false

时间:2016-04-19 05:12:06

标签: javascript

为什么javascript中的logical not operator会在Boolean valueBoolean object之间返回不同的结果?请考虑以下示例。

!true  // false
!false // true

!(new Boolean(true))  // false
!(new Boolean(false)) // false

spec开始,它表示正在评估的值转换为ToBoolean。如果参数是Object,ToBoolean将返回true,如果参数是布尔值,则返回原样。

进一步挖掘,ToBoolean也用于if语句和条件运算符等其他地方,请考虑以下示例:

var a = (new Boolean(false)) ? "unexpected" : "expected";
console.log(a); // unexpected

问题:布尔对象是一个Object还是一个布尔值?我们不应该将布尔对象评估为布尔值吗?

更新

我的问题被标记为this的重复问题。这个问题没有得到满意的答案,因为没有人回答我的问题,布尔对象是一个对象,还是布尔值?我们不应该将布尔对象评估为布尔值吗?

简单地知道布尔对象是一个对象是不够的,为什么它甚至存在,处理和/或设计具有布尔对象的对象的正确方法仍然没有答案。

5 个答案:

答案 0 :(得分:31)

  

object,无论是否具有属性,都不会默认为false ...

new Boolean(true)将返回object而非Boolean,而!{}将始终为false,因为{}truthy } value(Boolean({})将被评估为true

在处理Boolean工厂函数时,请勿使用new创建新实例(因为它将创建Boolean的新实例,并将返回object

Boolean(INPUT) 将返回指定primitive-Boolean的{​​{1}}值,该值可用于expression

来自docs, Boolean对象是comparison()

的对象包装器
  

说明: 如果需要,作为第一个参数传递的值将转换为boolean value值。如果省略值或boolean,则对象的初始值为0, -0, null, false, NaN, undefined, or the empty string ("")。所有其他值,包括任何对象或字符串" false",都会创建一个初始值为false的对象。

不要将原始布尔值true和false与布尔对象的true和false值混淆。

任何值不是trueundefined的对象,包括值为false的null,评估为Boolean object "传递给条件语句时。" [Reference]

例如,以下if语句中的条件求值为true



true

var x = new Boolean("false");
if (x) {
  console.log('x is true');
}

var y = new Boolean(false);
if (y) {
  console.log('y is true');
}




答案 1 :(得分:6)

Boolean是一个功能。根据调用类型,它在truthyfalsy方面具有不同的行为。

<强> 1。作为简单函数调用

当调用Boolean(value)作为简单函数时,它会验证参数是falsyfalsenullundefined,{{1} },''0)或Nan(所有其他值:对象实例,truthy1等)。这种类型的调用返回boolean primitive type 它按预期工作:

true

<强> 2。作为构造函数调用

与JavaScript中的任何函数一样,Boolean(null) // prints false Boolean(0) // prints false Boolean({}) // prints true Boolean(-1) // prints true 可以作为构造函数调用:Boolean。此调用类型返回boolean object instance 这引入了混乱,因为JavaScript将对象实例视为var b = new Boolean(value)值。

truthy

2.1为什么可以作为构造函数调用

JavaScript允许此构造函数调用为开发人员提供一种机制来保留var b = new Boolean(null); !!b // prints true, because b is an object instance if (b) { // b evaluates to true //executed code } 的属性创建。原始布尔类型不保存分配给它的属性。

boolean

2.2如何使布尔对象起作用

尽管如此,var booleanObject = new Boolean(null); booleanObject.foo = 'bar'; // create a property booleanObject.foo // prints 'bar' var booleanPrimitive = false; booleanPrimitive.foo = 'bar'; // create a property booleanPrimitive.foo // prints undefined 还有一种机制可以进行比较。与任何JavaScript对象一样,它有一个方法new Boolean(value),它返回valueOf()到布尔基元类型的转换(value用于truthy,true用于falsy):< / p>

false

为了使这项工作在条件中,有必要避免将布尔对象实例转换为truthy值。要实现这一点,请直接使用比较运算符var falsyBoolean = new Boolean(null); falsyBoolean.valueOf() // prints false, because null is falsy var truthyBoolean = new Boolean(1); truthyBoolean.valueOf() // prints true, because 1 is truthy

==

如果var falsyBoolean = new Boolean(null); falsyBoolean == false ? 'falsy' : 'truthy' // prints expected 'falsy' if (falsyBoolean == false) { //executed code } 运算符中的操作数是一个对象而另一个是基本类型,JavaScript会将其转换为基本类型,实际上包括在布尔对象上调用==方法。请参阅this article中的详细信息。

第3。如何不要混淆

最好的规则是避免使用valueOf()作为对象实例。 BooleanBoolean(value)足以验证变量真实状态。

答案 2 :(得分:1)

来自MDN's entry on Boolean

  

任何值未定义或为null的对象(包括值为false的Boolean对象)在传递给条件语句时计算结果为true。

     

例如,以下if语句中的条件求值为true:

  var x = new Boolean("false");
  if (x) {
    // this code is executed
  }

  var y = new Boolean(false);
  if (y) {
    // this code is also executed
  }

答案 3 :(得分:1)

使用true

时,falsenew Boolean(...)参数会得到相同的结果
  

Object-Oriented JavaScript Book, Stoyan Stefanov:

  您可以使用双重否定将任何值转换为其布尔等效值。   了解任何值如何转换为布尔值很重要。最值的   转换为true,但以下情况除外,它们转换为false

     

“”
null
undefined
0周年纪念

所以!!{}!!new Boolean(true)!!new Boolean(false)始终返回true

这种情况(没有双重否定):

if (new Boolean(true) === true) {

    console.log('this string will never be printed');
}

返回false,因为有不同的类型:

typeof new Boolean(true); // "object"
typeof true; // "boolean"

您必须仅按值比较它们才能获得预期结果:

if (new Boolean(true) == true) {

    console.log('Yay!');
}

new Boolean(true) == true; // true
new Boolean(true) === true; // false

另一个例子:

if (new Boolean(true) === new Boolean(true)) {

    console.log('this string will never be printed')
}

在这种情况下,您正在尝试比较对象。使用=====比较运算符,您将获得相同的结果。

  

Object-Oriented JavaScript Book, Stoyan Stefanov:

当你比较对象时,只有比较两个对象才会成真   引用同一个对象。比较两个不同的对象   碰巧有完全相同的方法,属性返回false。

不要使用布尔对象new Boolean(...)代替布尔基元。

答案 4 :(得分:0)

刚试过以下内容:

            alert(typeof true);    //alerts boolean
            alert(typeof new Boolean(true));   //alert object
            alert(typeof !(new Boolean(true)));   //alerts boolean
            alert(!(new Boolean(true)));         //alerts false

Rayon和Mukul都是对的,你只需要使用!Boolean(false) //返回true作为布尔值。