Javascript 有人能解释一下吗;双负';戏法

Javascript 有人能解释一下吗;双负';戏法,javascript,html,Javascript,Html,我绝对不是Javascript方面的专家,但我一直在阅读MarkPilgrim的网页,他提到了一些我想更好理解的东西 他说: 最后,使用双负技巧将结果强制为布尔值(true或false) 如果有人能更好地解释这一点,我将不胜感激 在javascript中,如果给定值为true、1、非null等,则使用“bang”运算符(!)将返回true。如果值为未定义、null、0或空字符串,则将返回false 因此,bang操作符将始终返回一个布尔值,但它将表示与开始时相反的值。如果您获取该操作的结果并再次

我绝对不是Javascript方面的专家,但我一直在阅读MarkPilgrim的网页,他提到了一些我想更好理解的东西

他说:

最后,使用双负技巧将结果强制为布尔值(true或false)

如果有人能更好地解释这一点,我将不胜感激

在javascript中,如果给定值为true、1、非null等,则使用“bang”运算符(!)将返回true。如果值为未定义、null、0或空字符串,则将返回false

因此,bang操作符将始终返回一个布尔值,但它将表示与开始时相反的值。如果您获取该操作的结果并再次“砰”一声,您可以再次将其反转,但仍然会得到一个布尔值(而不是未定义、null等)

两次使用bang将获取一个可能未定义的值、null等,并使其成为纯
false
。它将取一个可能为1的值,“true”等,并使其成为普通的
true

代码可能是这样写的:

var context = document.createElement('canvas').getContext;
var contextDoesNotExist = !context;
var contextExists = !contextDoesNotExist;
return contextExists;

逻辑NOT运算符
将值转换为与其逻辑值相反的布尔值

第二个
将以前的布尔结果转换回其原始逻辑值的布尔表示形式

对于逻辑NOT运算符:

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

因此,如果
getContext
给您一个“false”值,
将使其返回布尔值
false
。否则它将返回
true

“假”值为:

  • false
  • NaN
  • 未定义
  • null
  • (空字符串)
  • 0

如果
document.createElement('canvas').getContext
不是
undefined
null
,它将返回
true
。否则它将返回第一个
false

将变量强制为布尔类型并将其反转。第二个
再次反转(为您检查的内容提供原始(正确)布尔值)

为了清楚起见,最好使用

return Boolean(....);
将“某物”/“任何东西”强制转换为布尔值


返回原始布尔值(并保证表达式现在是布尔值,不管以前是什么)

这与JavaScript的弱类型有关<代码>文档。createElement('canvas')。getContext
是一个函数对象。通过预加一个
它将其作为布尔表达式进行计算,并翻转答案。通过在另一个
前面加上前缀,它将答案翻转回来。最终结果是函数将其作为布尔表达式进行计算,但返回实际的布尔结果,而不是函数对象本身。前置
是将表达式类型转换为布尔类型的一种快速而肮脏的方法。

Javascript有一组令人困惑的规则,用于在需要布尔类型的上下文中定义“真”和“假”。但是逻辑NOT运算符,
,始终生成正确的布尔值(常量
true
false
之一)。通过链接其中两个,成语
!!表达式
生成与原始表达式具有相同真实性的正确布尔值


你为什么要麻烦?因为它使您显示的函数更可预测。如果里面没有双负数,它可能返回
未定义的
,一个
函数
对象,或者与
函数
对象没有完全不同的东西。如果此函数的调用方对返回值做了一些奇怪的操作,则整个代码可能会出现错误(“奇怪”在这里表示“除了强制布尔上下文的操作之外的任何操作”)。双重否定习惯用法防止了这种情况。

document.createElement('canvas')。getContext
的计算结果可能是
未定义的
或对象引用<代码>!未定义的
产生
![某些对象]
产生
false
。这几乎就是我们需要的,只是颠倒过来。所以
用于将
未定义的
转换为
,并使用!!变量保证将类型转换为布尔值

给你一个简单的例子:

"" == false (is true)
"" === false (is false)

!!"" == false (is true)
!!"" === false (is true)
但是,如果您正在执行以下操作,则使用它是没有意义的:

var a = ""; // or a = null; or a = undefined ...
if(!!a){
...

if将其转换为布尔值,因此无需进行隐式双负转换。

boolean()
创建一个装箱布尔值,其行为与
创建的基本布尔值不同(例如,
typeof
将报告
“对象”
)。因此,
是首选。要使其返回基本布尔值:
返回(新布尔值(…)。valueOf()
@Zack它不适合我。它只在与
new
结合使用时才起作用。我知道这是一个有点过时的线程,但我认为重要的是要指出,bang-bang(!!)远比Boolean(val)更有效。这是一条非常古老的线索,但如果有人在研究bang(!!)方法与Boolean(val)方法的性能时遇到这一点,就像我所做的那样,Mad Man Moon之前的评论似乎不再正确。现在显示了在Chrome和Firefox中布尔(val)方法更快。这不是一组“混乱”的规则。@Abody97列表(上面显示的很有帮助)既不尽可能短(
false
;其他任何内容都需要显式比较运算符),也不尽可能长(至少添加
{}
[]
)。因此,你必须记住列表,而不是ru
var a = ""; // or a = null; or a = undefined ...
if(!!a){
...