16

我现在很困惑!JavaScript 中的运算符。我的理解是!运算符仅对布尔值进行操作。但是对我的一个答案的评论说它可以对任何东西进行操作并返回一个布尔值,这在我做了一些测试后恰好是真的。

alert(!undefined); //true
alert(!function(){}); //false
alert(!{}); //false
alert(!null); //true
alert(!()); //crash
alert(!"false"); //false
alert(!false)​;​​​​​​​​​​​​ //true​​​​​​​​​​​​​​​​​​

有人可以帮我概括一下!操作员。

编辑

更令人困惑的东西:

​alert( new String() == ""); //true
alert(!""); //true
alert(! new String()); //false

如何?​</p>

4

5 回答 5

20

!做你想的事:从真到假,反之亦然。奇怪的行为与 Javascript 如何将任何内容转换为truefalse.

http://11heavens.com/falsy-and-truthy-in-javascript

就像在 C 中一样(只有更糟),所有值都可以提升为 true 或 false。您想要的谷歌搜索术语是“真实”和“虚假”或“真实”和“虚假”。Truthy 表示某事转换为 true,falsy 表示某事转换为 false。null除了, undefined, 0, "", NaN, 和...之外,所有值都是真实的false

这个链接有更多有趣的例子:

http://www.sitepoint.com/javascript-truthy-falsy/

这个网站真的很喜欢用这里的有趣行为做病态的事情:

http://wtfjs.com

另请注意,==确实努力使事物具有可比性,而如果事物不可比,则===只会返回。falseCrockford in Javascript: The Good Parts建议不要==完全使用。

于 2012-05-22T21:58:35.500 回答
8

这与其说是一个函数,!不如说是truejavascript 中存在或不存在的函数。如果您熟悉强制转换,将变量强制转换为特定类型,那么您应该清楚以下内容。

!仅对布尔值进行操作。因此,您应用它的任何不是 boolean 的变量在应用之前首先被强制为 boolean !。将此与您的示例相关联:

Boolean(undefined) == false 

undefined 有点像 javascript 中的 null (有一些差异,但这是一个不同的主题)。布尔等效项应该是有意义的falseundefined不仅没有价值,它还声明您尝试使用的变量甚至不存在。

Boolean(function(){}) == true

函数是javascript中的对象。即使它是空的,它仍然具有函数对象共有的一些基本属性,因此它的布尔等效项是true. 这不是什么,所以它是一些东西。

Boolean({}) == true

像一个空函数,{}定义一个空对象。但是,它仍然具有 javascript 中对象共有的一些属性。它根本没有自定义属性。

Boolean(null) == false

正如我提到的undefinednull是相似的,但并不完全相同。它表明没有价值。

Boolean(()) // error

()对他们自己没有任何意义。您需要它们之间的一些东西来使语法正确,因此这与您的假/真问题无关。()单独只是一个语法错误。

Boolean("false") == true

"false"是一个字符串。仅仅因为它包含字母 f,a,l,s,e 并不能使其与布尔值相同false。非空字符串是某种东西,因此会强制转换为 Boolean true。注意字符串是一种特殊的对象,因为空字符串""强制转换false为空对象,{}如前所述,强制转换为true

布尔(假)==假

这个应该很清楚。 false已经是一个布尔值,所以转换它不会改变它的值。还是false

从那里,您可以看到应用!到每个案例将如何给您带来您所看到的结果。

为了进一步阅读,这是一篇关于 javascript 中类型强制的非常好的文章

更新:

关于你的String问题。String对象和字符串文字(用引号括起来的东西)之间存在差异。您可以从字符串文字创建String对象,但文字不会自动成为对象。javascript中的数字也是如此。JS 有一个Number对象,但您通常会定义数字文字。的行为Number与您所看到的一致String

alert( new Number() == 0); //true
alert(!0); //true
alert(! new Number()); //false

但是,正如您在评论中敏锐地提到的那样:

alert( new String() === ""); //false

由于类型不一样;对象与文字。

通常,Boolean(some_object)将始终评估为true但取决于确切的值,Boolean(some_literal)可能评估为假。

附录

仅仅因为本周早些时候我在脚上开枪,我认为这将是一个有用的信息。在大多数语言中,一个空数组[], 将被强制转换为false. 但是,在 Javascript 中,数组是对象,因此即使是空数组也会强制转换为true. 一个要提防的。在 js 和各种服务器端语言之间切换时,很容易出现错误,if(!maybe_empty_array){...}因为永远不会通过,因为maybe_empty_array总是会强制转换为true. 相反,您应该这样做if(maybe_empty_array.length){...}。如果数组为空,则其长度为 0,可以安全地强制转换为false.

于 2012-05-22T22:11:04.833 回答
5

“有人可以帮我概括一下!操作员的行为。”

当然。如果其单个操作数可以转换为 true,则返回 false;否则,返回真。

任何对象(包括“空”对象、{}或函数)、任何非空字符串和任何非零数都可以转换为真。另一方面,null、undefined、空字符串和零都将被转换为 false。然后!运算符返回相反的结果,因此您在问题中显示的结果。

于 2012-05-22T22:03:24.250 回答
3

!如果其单个操作数可以转换为 true,或者它是非布尔值,则返回 false:

!(x == y)
!"something" 

如果其操作数可以转换为 false,则为 true:

!(x > y)
于 2012-05-22T22:02:53.363 回答
0

很难写出比这更笼统的解释:

var arr = [0, "", false, null, undefined, NaN];

for(var i = 0; i < 6; i++){
    console.log(!(arr[i]));//always true
}

任何其他值都会产生false

于 2012-05-22T22:51:57.597 回答