JavaScript:为什么布尔值的按位或运算返回数字而不是布尔值?

11
我通过艰苦的方式发现在JavaScript中,对布尔类型进行位运算符操作不会返回布尔类型。我以为这可能是一个错误,但我查看了ECMAScript规范,确实指出位运算符返回数字而不是布尔型。它没有提到在使用布尔值时会出现什么奇怪的结果。为什么要这样做?我在其他语言中使用这种技术已有多年,所以我完全不知道为什么在JavaScript中它会产生不同的效果。 有任何想法吗?这只是因为除了我之外没有人会以这种方式使用位运算符,还是有技术上的原因?我无法想象检查类型并返回布尔类型会很困难。

以下代码供参考:

var found = false;
console.log(found, typeof(found));

found |= true;
console.log(found, typeof(found));

found = true;
console.log(found, typeof(found));

生成以下输出:

false 'boolean'
1 'number'
true 'boolean'

编辑:

应要求,我已经在C、C ++中使用过这个功能,我很确定也可以在PHP中使用,尽管我不能保证。是的,我意识到C / C ++是类型化的,因此内部会有所不同。我只是想知道为什么JavaScript的行为会不同。

应要求,这里是我通常如何使用| =的示例

var foundLowest = false;

for(var k = 0; k < someLength; ++k) {
    foundLowest |= someFunctionThatReturnsTF(k);
}

if(foundLowest === true) {
    /* do stuff */
}

1
你能否提供一些关于在布尔值上使用 |& 的实际用例示例? - Matías Fidemraizer
就此而言,你所说的支持布尔值 |= 的语言是什么? - T.J. Crowder
我认为位运算始终会返回数值,即使是对于布尔值也是如此;因为在底层它们本身就等同于数值。你为什么期望一个布尔值的返回呢? - Anthony Forloney
我不明白为什么要在布尔值上使用位运算符。如果你执行 true | false,结果是 true,但最终如果我想知道左边或右边哪个是 true,我会使用 ||(逻辑或)而不是 | - Matías Fidemraizer
1
很高兴看到有人真正检查规格! - T.J. Crowder
@AnthonyForloney 主要是因为在我使用的其他语言中可以这样做。C/C++ 是有类型的,我知道,但你可以在布尔值上使用 |=。我很确定我在 PHP 中也这样做过。 - SaganRitual
1个回答

9
具有一致行为的按位运算符(始终将其操作数转换为数字)似乎是它们被指定的足够好的理由。几年前,在es-discuss列表中曾经讨论过添加||=和类似的简写运算符,但Eich和他的团队非常保守,不愿意添加这样的东西,我记得有一条评论是“它的语法负担太大了”。:-)
请注意,因为JavaScript可以愉快地强制将任何值转换为布尔值,所以您可以放心使用当前的样式,并且仍然可以正常工作,因为true强制转换为1,而1又强制转换为true,false强制转换为0,而0又强制转换为false。例如:

var a = false;

a |= true;
// Even though `a` is now `1`, it works just fine
if (a) {
  snippet.log(a + " => if branch"); // Does this one
} else {
  snippet.log(a + " => else branch");
}

a &= false;
// Even though `a` is now `0`, it works just fine
if (a) {
  snippet.log(a + " => if branch");
} else {
  snippet.log(a + " => else branch"); // Does this one
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>


嘿嘿,是啊,我只是对类型强制转换有点过于谨慎。我使用类型安全的相等/不等运算符,并且当我忘记时,我会让jshint提醒我。我想这可能是因为我受到了C/C++的影响。特别是C++,有无数种通过构造函数进行隐式转换可能会导致问题的方式。 - SaganRitual
1
@GreatBigBore:类型强制转换确实很棘手,但其中的真值/假值子集相当简单明了:假值包括 0NaN""nullundefined 和当然是 false;其他所有值都是真值。 - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接