布尔对象上的逻辑 NOT 在 Javascript 中总是返回 false

Logical NOT on Boolean Object always return false in Javascript

本文关键字:Javascript false 返回 NOT 对象 布尔      更新时间:2023-09-26

为什么 javascript 中的逻辑 not 运算符在布尔值和布尔对象之间返回不同的结果?请考虑以下示例。

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

从规范中,它说正在评估的值转换ToBoolean .如果参数是 Object,ToBoolean 将返回 true,如果参数是布尔值,则按原样返回。

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

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

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


更新

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

仅仅知道布尔对象是一个对象是不够的,为什么它甚至存在,以及处理和/或设计布尔对象的正确方法是什么,但仍未得到回答。

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

new Boolean(true)将返回一个不Boolean object,并且!{}将始终false,因为{}是一个truthy值(Boolean({})将被评估为true (

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

Boolean(INPUT)将返回primitive-Boolean可用于comparison的指定expression的值

从文档中,布尔对象是boolean value(( 的对象包装器

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

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

任何值不undefinednull的对象,包括值为 false 的Boolean object,">当传递给条件语句时">计算结果为true。[参考资料]

例如,以下 if 语句中的条件计算结果为 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');
}
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

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

1. 作为简单函数调用

当调用Boolean(value)作为简单函数时,它会验证参数是falsy(falsenullundefined''0Nan(还是truthy(所有其他值:对象实例、1true等(。这种类型的调用返回布尔基元类型。
它按预期工作:

Boolean(null) // prints false
Boolean(0)    // prints false
Boolean({})  // prints true
Boolean(-1)  // prints true

2. 作为构造函数调用

像 JavaScript 中的任何函数一样,Boolean 可以作为构造函数调用:var b = new Boolean(value) 。此调用类型返回布尔对象实例。
这会带来混乱,因为 JavaScript 将对象实例视为truthy值。

var b = new Boolean(null);
!!b // prints true, because b is an object instance
if (b) { // b evaluates to true
   //executed code 
}

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

JavaScript 允许此构造函数调用为开发人员提供一种机制来保留boolean的属性创建。基元布尔类型不会保存分配给它的属性。

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

2.2 如何使布尔对象工作

尽管如此,new Boolean(value)有一个机制来进行比较。像任何JavaScript对象一样,它有一个方法valueOf(),它返回value到布尔基元类型的转换(true表示真,false表示假(:

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 会将其转换为基元类型,这实际上包括在布尔对象上调用 valueOf() 方法。请参阅本文的更多详细信息。

3. 如何不感到困惑

最好的规则是完全避免将Boolean用作对象实例。 Boolean(value)!!value足以验证变量真实状态。

来自 MDN 关于布尔值的条目:

任何值未定义或 null 的对象(包括值为 false 的布尔对象(在传递给条件语句时计算结果为 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
  }

使用 new Boolean(...) 时,truefalse 参数将获得相同的结果

面向对象的JavaScript Book,Stoyan Stefanov:

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

"

未定义
0
NaN

所以!!{}!!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')
}

在本例中,您正在尝试比较对象。使用 =====比较运算符,您将获得相同的结果。

面向对象的JavaScript Book,Stoyan Stefanov:当你比较对象时,

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

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

刚刚尝试了以下方法:

            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)//return true 作为布尔值。