为什么javascript中的logical not operator会在Boolean value和Boolean 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的重复问题。这个问题没有得到满意的答案,因为没有人回答我的问题,布尔对象是一个对象,还是布尔值?我们不应该将布尔对象评估为布尔值吗?
简单地知道布尔对象是一个对象是不够的,为什么它甚至存在,处理和/或设计具有布尔对象的对象的正确方法仍然没有答案。
答案 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值混淆。
任何值不是true
或undefined
的对象,包括值为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
是一个功能。根据调用类型,它在truthy
和falsy
方面具有不同的行为。
<强> 1。作为简单函数调用
当调用Boolean(value)
作为简单函数时,它会验证参数是falsy
(false
,null
,undefined
,{{1} },''
,0
)或Nan
(所有其他值:对象实例,truthy
,1
等)。这种类型的调用返回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()
作为对象实例。 Boolean
或Boolean(value)
足以验证变量真实状态。
答案 2 :(得分:1)
任何值未定义或为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
false
和new 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作为布尔值。