我绝不是Javascript的专家,但我一直在阅读Mark Pilgrim的"Dive into HTML5"网页,他提到了一些我想要更好理解的内容。
他说:
最后,您使用双重否定技巧将结果强制为布尔值(true或false)。
function supports_canvas() {
return !!document.createElement('canvas').getContext;
}
如果有人能够更好地解释这一点,我会很感激!
答案 0 :(得分:244)
逻辑NOT运算符!
将值转换为与其逻辑值相反的布尔值。
第二个!
将前一个布尔结果转换回其原始逻辑值的布尔表示。
如果单个操作数可以转换为true,则返回false;否则,返回true。
因此,如果getContext
给您一个“假”值,!!
将返回布尔值false
。否则它将返回true
。
“假”值是:
false
NaN
undefined
null
""
(空字符串)0
答案 1 :(得分:29)
当放置在期望布尔值的上下文中时,Javascript对于被认为是“真”和“假”的内容有一组令人困惑的规则。但逻辑NOT运算符!
始终生成一个适当的布尔值(常量true
和false
之一)。通过链接其中两个,成语!!expression
产生一个与原始表达式具有相同真实性的适当布尔值。
你为什么要打扰?因为它使您显示的功能更加可预测。如果它没有双重否定,它可能会返回undefined
,Function
对象,或者与Function
对象完全不同的东西。如果这个函数的调用者对返回值做了一些奇怪的事情,那么整个代码可能会出错(这里的“怪异”意味着“除了强制执行布尔上下文的操作之外的任何东西”)。双阴性成语阻止了这一点。
答案 2 :(得分:14)
在javascript中,如果给定值为true,则为1,而不是null等,使用“bang”运算符(!)将返回true。如果值为undefined,null,0或空字符串,则返回false
因此,bang运算符将始终返回一个布尔值,但它将代表您开始使用的相反值。如果您获取该操作的结果并再次“敲击”它,您可以再次反转它,但仍然以布尔结尾(而不是未定义,null等)。
使用bang两次将获取一个可能未定义,null等的值,并使其仅为false
。它将采用可能为1,“真实”等的值,并使其仅为true
。
代码可以写成:
var context = document.createElement('canvas').getContext;
var contextDoesNotExist = !context;
var contextExists = !contextDoesNotExist;
return contextExists;
答案 3 :(得分:11)
使用!!变量可以保证对布尔值进行类型转换。
举个简单的例子:
"" == false (is true)
"" === false (is false)
!!"" == false (is true)
!!"" === false (is true)
但是,如果您正在执行以下操作,那么使用它是没有意义的:
var a = ""; // or a = null; or a = undefined ...
if(!!a){
...
if会将它强制转换为boolean,因此不需要进行隐式双负投射。
答案 4 :(得分:7)
!
向boolean
投射“某事”/“任何内容”。
!!
返回原始布尔值(并保证表达式现在是布尔值,不管以前是什么)
答案 5 :(得分:5)
第一个!
将变量强制转换为布尔类型并将其反转。第二个!
再次将其反转(为您检查的任何内容提供原始(正确)布尔值。)
为了清楚起见,最好使用
return Boolean(....);
答案 6 :(得分:4)
document.createElement('canvas').getContext
可以评估为undefined
或对象引用。 !undefined
产生true
,![some_object]
产生false
。这几乎就是我们所需要的,只是倒置了。因此!!
用于将undefined
转换为false
,将对象引用转换为true
。
答案 7 :(得分:3)
这与JavaScript的弱打字有关。 document.createElement('canvas').getContext
是一个函数对象。通过预先添加单个!
,它将它作为布尔表达式进行计算并翻转答案。通过预先添加另一个!
,它会将答案翻转回来。最终结果是函数将其计算为布尔表达式,但返回实际的布尔结果而不是函数对象本身。前置!!
是一种快速而又脏的方法,可以将表达式强制转换为布尔类型。
答案 8 :(得分:2)
如果document.createElement('canvas').getContext
不是undefined
或null
,则会返回true
。否则它将返回false
。