了解JavaScript中的类型强制

时间:2019-02-15 23:44:07

标签: javascript node.js type-coercion

我知道==运算符执行类型强制。但我无法理解以下行为。

const x = new Boolean(false);

if (x) {
  console.log("if(x) is true");
}

if (x == false) {
  console.log("if(x == false) is true");
}

令人惊讶的是,在摘要上方显示了两行:

if(x) is true if(x == false) is true

有人可以解释这种奇怪的行为吗?或者我缺少一些基本的东西?

5 个答案:

答案 0 :(得分:4)

如其他答案所述,这是因为x是一个对象–一个布尔对象,但仍然是一个对象,因为您正在使用new运算符–并且仅当您比较{ {1}}到xfalse正在检查if (x)是否为truthy值,因此不需要强制(不涉及其他操作数):一个对象始终是“ true”(weeeell…几乎总是:x返回typeof null,但这是一个虚假的值。但这是另一个故事……)。

您可以轻按toPrimitive符号来轻松检查何时调用强制:

object

答案 1 :(得分:1)

由于Boolean(false)是一个函数,因此您应该使用new Boolean(false)而不是Boolean

否则,您将得到一个空对象{},它与函数本身返回的类型boolean的类型不同。

const x = new Boolean(false);
const y = Boolean(false);

console.log(x, typeof x);
console.log(y, typeof y);

在您的第一个测试中,您仅检查值是否为真,而空对象是否为真,因为x = {},测试通过:

const x = new Boolean(false);

console.log(x, !!x, !!{}, Boolean(x))

if (x) {
  console.log("if(x) is true");
}

但是,当使用==时,运算符使用new Boolean(false)的{​​{3}}将false强制为其原始值,从而相等。

const x = new Boolean(false);

console.log(x.valueOf())

答案 2 :(得分:1)

new Boolean(false)产生一个对象。即使对象包装虚假的原始值,它们也始终是truthy。例如,尽管new String("")虚假,""也是真实的。

另一方面,当您执行new Boolean(false) == false时,它会将对象强制为其原始值以进行比较。顺便说一句,new Boolean(false) === false not true,因为它们的类型不匹配。

通常,除非有特殊原因,否则不应将对象构造函数用于原始类型,以免发生此类意外行为。

答案 3 :(得分:1)

如果您写

const x = new Boolean(false);

typeof x将返回object。类型object是“ truthy”,这意味着如果没有像==这样的运算符,则它的值为true。但是,它的值为false,这就是第二条语句也计算为true的原因。

因此if语句的行为有所不同,因为没有操作符的if会检查类型是true还是falsy(在这种情况下为true-> true),以及带有比较(==)的if呼叫.valueOf(),即false

在这种情况下,您都不应使用new包装器。

const x = false;

就足够了。对于投射,您可以使用Boolean(),而无需使用new包装器。

要检查一个值是否真实,可以使用双重否定:

const x = new Boolean(false);

if (x) console.log(!!x);

if (x == false) console.log(x.valueOf());

答案 4 :(得分:1)

当您在javascript中执行if (expression)时,表达式会通过强制转换为布尔值来评估。

有些困惑,Boolean(new Boolean(false))的计算结果为true,因为正如尼克所说,它仍然是一个对象。这就是引起您困惑的行为的原因。

好读的书以获得更多信息https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/