是什么 !!(不是)JavaScript中的运算符?


3103

我看到了一些代码,似乎以两个感叹号的形式使用了我不认识的运算符,如下所示:!!。有人可以告诉我这个操作员做什么吗?

我看到的背景是

this.vertical = vertical !== undefined ? !!vertical : this.vertical;

944
通过“砰,砰,你是布尔值”记住它
Gus 2012年

75
仅作记录,请勿执行此处引用的内容。实际操作if(vertical !== undefined) this.vertical = Boolean(vertical);-发生的事情更加清晰明了,不需要不必要的分配,完全是标准的,并且速度与jsperf.com/boolean-conversion-speed一样快(在当前FF和Chrome上)。
Phil H

72
!! 不是运算符。只是!操作员两次。
Vivek 2014年

11
仅作记录,Boolean(5/0)!!5/0
schabluk

63
@schabluk,记录下来,操作顺序!!5/0产生的原因,Infinity而不是true由产生的Boolean(5/0)!!5/0等于(!!5)/0-又名true/0--由于!运算符的优先级高于/运算符。如果您想5/0使用双爆炸来布尔化,则需要使用!!(5/0)
2015年

Answers:


2742

转换Objectboolean。如果是falsey(例如0nullundefined等),这将是false,否则,true

!oObject  // inverted boolean
!!oObject // non inverted boolean so true boolean representation

因此!!,不是运算符,只是!运算符的两倍。

真实示例“测试IE版本”:

const isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);  
console.log(isIE8); // returns true or false 

如果你⇒

console.log(navigator.userAgent.match(/MSIE 8.0/));  
// returns either an Array or null  

但是如果你⇒

console.log(!!navigator.userAgent.match(/MSIE 8.0/));  
// returns either true or false

123
它将非布尔值转换为反布尔值(例如,!5将为假,因为5在JS中为非假值),然后对布尔值进行求反,以便将原始值作为布尔值获得(所以!! 5将是真的)。
Chuck

110
一个简单的描述方法是:Boolean(5)=== !! 5; 相同的转换,更少的字符。
米卡·斯奈德

39
这用于将真实值转换为布尔值true,而将虚假值转换为布尔值false。
thetoolman

13
@Micah Snyder请注意,在JavaScript中最好使用布尔型原语,而不是使用新的Boolean()创建将布尔值装箱的对象。下面是一个例子,可以看出两者的区别:jsfiddle.net/eekbu
victorvartan

4
据我所知,这种爆炸式模式在if(…_语句内;仅在应返回布尔值的函数的return语句内无用。)
rds

853

这是进行类型转换的令人费解的方法。

!不是。所以!truefalse!falsetrue!0true!1false

因此,您要将一个值转换为布尔值,然后将其求反,然后再次将其求反。

// Maximum Obscurity:
val.enabled = !!userId;

// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;

// And finally, much easier to understand:
val.enabled = (userId != 0);

73
!!假=假。!! true = true
cllpse

89
这里的“更容易理解”变体真的更容易理解吗?对0的检查不是对0的实际检查,而是对Javascript认为等于0的怪异值列表的检查。 userId ? true : false 更清楚地说明正在进行转换,并处理了userId的值可能已显式设置为undefined
本·雷根斯潘

54
我的大脑在解码!!varBoolean(var)..时没有任何问题,!!并且比其他方法更快(处理指令更少)且更短。
adamJLev

7
@RickyClarkson主要是出于可读性,因为从语法上讲它不是必需的。有些人使用总是在括号中加上条件的约定来将其与表达式的其余部分区分开。
戴夫·拉格

8
我不同意这一点。userId != 0对和是正确的null, 但对则是错误的。如果您确实想要这种行为,则可能应该对此明确。但是,即使它的工作原理与完全相同,也不清楚是否在此处将这些值设置为false,或者是否只是没有考虑Javascript的类型转换规则。NaNundefinedfalse!!userId
菲尔2014年

449

!!expr根据表达式的真实性返回布尔值(truefalse)。在非布尔类型上使用时更有意义。考虑以下示例,尤其是第三个示例及以后的示例:

          !!false === false
           !!true === true

              !!0 === false
!!parseInt("foo") === false // NaN is falsy
              !!1 === true
             !!-1 === true  // -1 is truthy

             !!"" === false // empty string is falsy
          !!"foo" === true  // non-empty string is truthy
        !!"false" === true  // ...even if it contains a falsy value

     !!window.foo === false // undefined is falsy
           !!null === false // null is falsy

             !!{} === true  // an (empty) object is truthy
             !![] === true  // an (empty) array is truthy; PHP programmers beware!

63
值得注意的是:!!new Boolean(false) // true
Camilo Martin

43
...但也!!Boolean(false) // false
卡米洛·马丁

97
new Boolean(false)是一个对象,即使它包含虚假值,它也是真实的!
Salman A

3
是的,我知道,但是考虑到,最原始的构造函数(StringNumberDate等)是指可以被调用的功能太,但在这种情况下,结果是不同的!
卡米洛·马丁

4
@CamiloMartin:刚意识到new Boolean(false)返回object一会儿就会Boolean(false)返回原始值 false。希望这是有道理的。
Salman A

155

冲泡一些茶:

!!不是运算符。它是-的双重用途,!它是逻辑上的“非”运算符。


理论上:

! 确定什么不是值的“真相”:

  • 事实是false并非如此true(这就是!false导致的原因true

  • 事实是true并非如此false(这就是!true导致的原因false


!!确定不是值的“真相” :

  • 事实是true并非如此 true(这就是!!true导致的原因true

  • 事实是false并非如此 false(这就是!!false导致的原因false


我们希望在比较中确定的是关于参考值的“真实性” ,而不是参考本身的。在一个用例中,即使我们期望该值是false(或错误的),或者期望该值不是typeof ,我们也可能想知道关于值的真相boolean


在实践中:

考虑一个简洁的功能,该功能通过动态类型(也称为“鸭子类型”)检测功能(在这种情况下为平台兼容性)。我们想编写一个函数,true如果用户的浏览器支持HTML5 <audio>元素,则该函数返回,但是如果<audio>函数未定义,我们不希望该函数抛出错误;并且我们不想使用try ... catch任何可能的错误(因为它们很严重);而且我们也不想在函数内部使用不会始终揭示该功能真相的检查(例如,即使不支持HTML5 ,它document.createElement('audio')仍会创建一个名为的元素)。<audio><audio>


这是三种方法:

// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }

// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }

// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }

foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true

每个函数都接受a <tag>和an 的自变量attribute,但是它们根据比较确定的结果返回不同的值。

但是,等等,还有更多!

你们中的某些人可能已经注意到,在这个特定的示例中,可以使用性能更高的方法简单地检查属性,以检查所讨论的对象是否具有属性。有两种方法可以做到这一点:

// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }

// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }

qux('audio', 'preload');  // returns true
quux('audio', 'preload'); // returns true

我们离题了...

无论这些情况有多么罕见,都可能存在一些情况,其中最简洁,最有效,因此最优选的true从非布尔值,可能未定义的值中获取的方法是使用!!。希望这很荒谬。


1
完全棒的答案,但我看不到!!的效用!构造。由于一条if()语句已经将表达式转换为布尔值,因此将测试函数的返回值显式转换为布尔值是多余的-因为就if()语句而言,“真实性” === true 。还是我错过了一个需要真实表示布尔值的场景true
汤姆·奥格

1
@TomAuger if()语句确实对伪造的值强制转换为布尔值,但是说您实际上想在对象上设置一个布尔标志-它不会像if()语句那样强制转换。例如object.hasTheThing = !!castTheReturnValToBoolNoMatterWhat()将设置truefalse代替实际的返回值。另一个例子是,所有管理员均为id0而非管理员为id 1或更高。要获得true某人是否不是管理员的信息,您可以这样做person.isNotAdmin = !!admin.id。用例很少,但是使用起来很简洁。
本尼

103

!!将其右侧的值转换为其等效的布尔值。(想想穷人的“类型转换”方式)。它的意图是通常传达给读者,代码并不关心什么值是可变的,但它的“真”值是。


4
或在右侧为布尔值的情况下,它什么也不做。
Daniel A. White

3
@Daniel:!仍将值向右翻转。对于布尔!值,最右边的值将取反,而最左边的值将!再次取反。最终结果是没有变化,但是大多数引擎都会为双重否定生成操作码。

但是有什么意义呢?如果我这样做,if(0){...Javascript已经知道这是错误的。为什么更好说呢if(!!0){...
CodyBugstein '16

重点是针对您可能不知道其内容的变量;如果它可以是整数或字符串,对象或null,未定义等,则这是测试存在性的简便方法。
mix3d 16/09/22

71

!!foo将两次unary not运算符应用两次,并用于将其转换为布尔类型,类似于使用unary plus +foo将其转换为数字并连接一个空字符串''+foo以将其转换为字符串。

除了这些技巧外,您还可以使用与原始类型相对应的构造函数(使用new)来显式转换值,即

Boolean(foo) === !!foo
Number(foo)  === +foo
String(foo)  === ''+foo

但是随后您可能会遇到instanceof的问题。新的Boolean(1)instanceof对象-> true !! 1 instanceof对象-> false
Seamus 2010年

13
不,你不能:请注意,构造函数被调用时没有new-在我的答案是明确提到
克里斯托夫

2
太棒了!当您需要将“ 0”的字符串评估为false而不是true时,这对小技巧很有用。(即从selects读取值时,因为它们被读取为String)。因此,如果您想将“ 0”视为负数(布尔值为false),则x="0"只需执行一下操作:x=!!+x; //falseBoolean(Number(x))Number(或+ x)相同,会将字符串“ 0”转换为0,DOES会将其评估为false,然后将布尔值(!! x)将其直接转换为布尔值。十分简单!
DiegoDD

2
@DiegoDD为什么您会选择!!+xvs x !== "0"
placeybordeaux 2015年

@placeybordeaux,因为例如您可能想转换该值并将其分配给其他变量,而不管是否要将其与其他变量进行比较。
DiegoDD

67

这么多的答案完成了一半的工作。是的,!!X可以理解为“ X(表示为布尔值)的真实性”。但是!!,实际上,对于弄清单个变量是真实的还是虚假的,并不是那么重要。!!myVar === true和刚好一样myVar。与!!X“真实”布尔值进行比较并没有真正的用处。

您将获得以可重复,标准化(和JSLint友好)方式相互!!检查多个变量的真实性的能力。

简单地铸造:(

那是...

  • 0 === falsefalse
  • !!0 === falsetrue

以上不是那么有用。if (!0)给您与相同的结果if (!!0 === false)。我想不出将变量转换为布尔值然后与“ true”布尔值进行比较的好例子。

请从JSLint的指导中查看“ ==和!=“ (注意:Crockford 会将其站点稍微移动一下;该链接可能会在某个时间点消失),其中有一些原因:

==和!=运算符会在比较之前键入强制。这很糟糕,因为它导致'\ t \ r \ n'== 0为真。这可以掩盖类型错误。JSLint无法可靠地确定==是否正确使用,因此最好不要使用==和!=,而始终使用更可靠的===和!==运算符。

如果只在乎某个值是真实的还是虚假的,则使用缩写形式。代替
(foo != 0)

说啊
(foo)

而不是
(foo == 0)


(!foo)

请注意,有一些直观的情况下,其中一个布尔值将被转换为数值(true强制转换1false0比较一个布尔值的号码时)。在这种情况下,!!可能对精神有用。同样,在这些情况下,您正在将非布尔值与硬类型的布尔值进行比较,这是一个严重的错误。 if (-1)仍然是去这里的路。

╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
               Original                    Equivalent       Result   
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
 if (-1 == true) console.log("spam")    if (-1 == 1)       undefined 
 if (-1 == false) console.log("spam")   if (-1 == 0)       undefined 
   Order doesn't matter...                                           
 if (true == -1) console.log("spam")    if (1 == -1)       undefined 
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
 if (!!-1 == true) console.log("spam")  if (true == true)  spam       better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
 if (-1) console.log("spam")            if (truthy)        spam       still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝

而且取决于您的引擎,事情变得更加疯狂。以WScript为例。

function test()
{
    return (1 === 1);
}
WScript.echo(test());

由于Windows某些历史记录,将在消息框中输出-1!在cmd.exe提示中尝试一下,看看!但WScript.echo(-1 == test())仍然给您0或WScript的false别看 太可怕了

比较真实性:)

但是,如果我有两个值需要检查真实性/虚假性,该怎么办?

假装我们有myVar1 = 0;myVar2 = undefined;

  • myVar1 === myVar20 === undefined而且显然是错误的。
  • !!myVar1 === !!myVar2!!0 === !!undefined,是真的!同样的真实性!(在这种情况下,两个“都具有虚假的真实性”。)

因此,您真正需要使用“布尔值转换变量”的唯一地方是,如果您要检查两个变量是否具有相同的真实性,对吗?也就是说,使用!!,如果你需要查看两个瓦尔是既truthy或两者falsy(或没有),也就是相等(或没有)感实性

我无法想到一个出色的,非人为的用例。也许您具有表单中的“链接”字段?

if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
    errorObjects.spouse = "Please either enter a valid name AND age " 
        + "for your spouse or leave all spouse fields blank.";
}

因此,现在,如果您对配偶双方的姓名和年龄均不真实,或者对配偶姓名和年龄均不真实,则可以继续。否则,您只有一个带有值的字段(或者很早就安排了婚姻),并且需要在errorObjects集合上创建一个额外的错误。


编辑2017年10月24日,19年2月6日:

期望显式布尔值的第三方库

这是一个有趣的情况... !!当第三方库期望显式布尔值时可能会有用。

例如,JSX(React)中的False具有特殊含义,不会因简单的虚假行为而触发。如果您尝试在JSX中返回类似以下的内容,则期望int messageCount...

{messageCount && <div>You have messages!</div>}

...当您收到0零条消息时,看到React渲染一个可能会让您感到惊讶。您必须显式返回false才能使JSX无法呈现。上面的语句返回0,由JSX愉快地呈现。它不能告诉您没有Count: {messageCount && <div>Get your count to zero!</div>}(或其他较不人为的东西)。

  • 一种解决方法是将bangbang强制0转换为!!0,即false
    {!!messageCount && <div>You have messages!</div>}

  • JSX的文档建议您更加明确,编写自我注释的代码,并使用比较来强制使用布尔值。
    {messageCount > 0 && <div>You have messages!</div>}

  • 我更愿意用三元来处理虚假行为-
    {messageCount ? <div>You have messages!</div> : false}

在Typescript中也是如此:如果您有一个返回布尔值的函数(或者您正在为布尔变量赋值),则[通常]您不能返回/分配布尔y值;它必须是一个强类型的布尔值。这意味着,iff myObject是强类型的return !myObject;适用于返回布尔值的函数,但return myObject;不能返回布尔值。您必须return !!myObject符合Typescript的期望。

Typescript例外?如果myObjectany,则返回JavaScript的Wild West !!,即使返回类型为布尔值,也可以不带返回。

请记住,这些是JSX和Typescript约定,而不是JavaScript固有的约定

但是,如果0在渲染的JSX中看到奇怪的,请考虑宽松的虚假管理。


很好的解释。所以你会说!在此工作人员特征检测示例中是否不是严格必要的? if (!!window.Worker)
jk7 2015年

2
不,您不需要它。真实性和true“外部性”在一个语言中的作用完全相同if。我一直在尝试,但是除了上面提到的复杂的“比较真实性”情况之外,我想不出为什么更喜欢将真实性转换为布尔值的原因,但是如果以后再使用该值则可读性更高,例如在q库示例中。但是即使那样,这也是一条信息丢失的捷径,我认为您最好每次都评估真实性。
鲁芬2015年

React是我们开始使用!!的主要原因。模式,但这恰好是一件非常方便且可重复的事情。我只需要担心事物的真实性或虚假性,而不用担心底层类型是什么。

没有评论的投票难以解决您的问题!让我知道什么看起来不好,我很乐意解决。
鲁芬

55

它只是逻辑非运算符,两次-用于将某些内容转换为布尔值,例如:

true === !!10

false === !!0

3
你到底为什么要这样做?使用 !运算符转换为布尔值,然后使用===比较类型?只需接受您没有类型安全性,并执行val> 0之类的操作即可。
达伦·克拉克

43
@Darren:他没有比较类型;他通过在回答中写断言来告诉您结果是什么。
Lightness Races in Orbit


26

这是双重not操作。第一个!将值转换为布尔值,然后将其逻辑值反转。第二个!将逻辑值反向。


26

似乎!!运算符导致双重否定。

var foo = "Hello World!";

!foo // Result: false
!!foo // Result: true

23

它模拟了Boolean()强制转换功能的行为。NOT无论给定什么操作数,第一个都返回布尔值。第二个取反NOTBoolean值,因此给出true变量的布尔值。最终结果与Boolean()在值上使用函数相同。



18

我认为值得一提的是,结合了逻辑AND / OR的条件将不会返回布尔值,但是在&&的情况下,最后一次成功或第一次失败,而在||的情况下,第一次成功或最后一次失败 条件链。

res = (1 && 2); // res is 2
res = (true && alert) // res is function alert()
res = ('foo' || alert) // res is 'foo'

为了将条件转换为真实的布尔文字,我们可以使用双重否定:

res = !!(1 && 2); // res is true
res = !!(true && alert) // res is true
res = !!('foo' || alert) // res is true

17

!!它使用NOT两次运算,!将值转换为a boolean并将其反转,这是一个简单的示例,了解其!!工作原理:

首先,您拥有的地方:

var zero = 0;

然后!0,将其转换为boolean并被评估为true,因为0为falsy,因此您获得了相反的值并转换为boolean,因此其被评估为true

!zero; //true

但是我们不希望值的布尔值取反,因此我们可以再次将其取反以获得结果!这就是为什么我们使用另一个!

基本上,请!!确保我们得到的值是布尔值,而不是虚假,真实或字符串等。

因此,就像Boolean在javascript中使用function 一样,但是将值转换为boolean的简便快捷方式:

var zero = 0;
!!zero; //false



10

我怀疑这是C ++的残over剩饭,在这里人们会重写!运算符,但不是布尔运算符。

因此,在这种情况下要获得否定(或肯定)答案,您首先需要使用!运算符以获取布尔值,但是如果要检查肯定的情况,则可以使用!!。


10

ifwhile报表,?操作者使用真值来确定的代码分支运行。例如,零和NaN数字和空字符串为false,但其他数字和字符串为true。对象为true,但未定义的值null都为false。

双重否定运算符!!计算值的真值。实际上是两个运算符,其中!!xmeans是!(!x),其行为如下:

  • If x是一个错误值,!xis true!!xis false
  • If x是一个真值,!xis false!!xis true

当在布尔上下文的顶层中使用(ifwhile,或?),所述!!操作者是行为上无操作。例如,if (x)if (!!x)意思相同。

实际用途

但是,它有一些实际用途。

一种用途是将对象有损地压缩到其真实值,这样您的代码就不会保留对大对象的引用并使它保持活动状态。分配!!some_big_object给变量而不是some_big_object为垃圾收集器释放它。这对于产生对象或错误值(例如null或未定义值)(例如浏览器功能检测)的情况很有用。

我在关于C的对应!!运算符答案中提到的另一种用法是使用“毛绒”工具,这些工具可以查找常见的错字和打印诊断信息。例如,在C和JavaScript中,布尔运算的一些常见错别字都会产生其他行为,其输出与布尔值不太相同:

  • if (a = b)是赋值之后是使用的真值b; if (a == b)是平等比较。
  • if (a & b)是按位与;if (a && b)是逻辑AND。2 & 50(错误值);2 && 5是真的。

!!运营商再次向皮棉工具,你写的是你的意思:当前操作,然后取结果的真值。

第三种用途是产生逻辑XOR和逻辑XNOR。在C和JavaScript中,都a && b执行逻辑AND(如果双方均为true,则为true),然后a & b执行按位AND。a || b执行逻辑或(如果至少一个为true,则为true),然后a | b执行按位OR。有一个按位XOR(异或)a ^ b,但没有用于逻辑XOR的内置运算符(如果恰好一侧为true,则为true)。例如,您可能希望允许用户在两​​个字段之一中恰好输入文本。您可以做的是将每个转换为真值并进行比较:!!x !== !!y



8

这里有很多不错的答案,但是如果您已经读了那么远,这有助于我“了解”。在Chrome(等)上打开控制台,然后开始输入:

!(!(1))
!(!(0))
!(!('truthy')) 
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)

当然,这些都与仅键入!! someThing相同,但是添加的括号可能有助于使其更易于理解。


8

!!x 是的简写 Boolean(x)

第一次爆炸会迫使js引擎运行,Boolean(x)但也会产生反转值的副作用。因此,第二次爆炸消除了副作用。


8

它将所有事物强制为布尔值。

例如:

console.log(undefined); // -> undefined
console.log(!undefined); // -> true
console.log(!!undefined); // -> false

console.log('abc'); // -> abc
console.log(!'abc'); // -> false
console.log(!!'abc'); // -> true

console.log(0 === false); // -> undefined
console.log(!0 === false); // -> false
console.log(!!0 === false); // -> true

7

这个问题已经得到了相当彻底的回答,但是我想补充一个我希望尽可能简化的答案,使之具有!!的含义!尽可能简单地掌握。

因为javascript具有所谓的“真值”和“假值”,所以有些表达式在其他表达式中求值时会导致为真或假条件,即使所检查的值或表达式实际上不是truefalse

例如:

if (document.getElementById('myElement')) {
    // code block
}

如果该元素确实存在,则表达式将求值为true,并将执行代码块。

然而:

if (document.getElementById('myElement') == true) {
    // code block
}

...将不会导致真正的情况,并且即使元素确实存在,也不会执行代码块。

为什么?因为document.getElementById()是一个“真实的”表达式,在该if()语句中其结果为true ,但不是的实际布尔值true

在这种情况下,双“ not”非常简单。not背对背仅两个秒。

第一个简单地“反转”真实值或falsey值,从而产生实际的布尔类型,然后第二个简单地将其“反转”回到其原始状态,但现在变为实际的布尔值。这样,您就可以保持一致性:

if (!!document.getElementById('myElement')) {}

if (!!document.getElementById('myElement') == true) {}

都将按预期返回true。


7

我只是想补充一点

if(variableThing){
  // do something
}

是相同的

if(!!variableThing){
  // do something
}

但是,当某些内容未定义时,这可能是个问题。

// a === undefined, b is an empty object (eg. b.asdf === undefined)
var a, b = {};

// Both of these give error a.foo is not defined etc.
// you'd see the same behavior for !!a.foo and !!b.foo.bar

a.foo 
b.foo.bar

// This works -- these return undefined

a && a.foo
b.foo && b.foo.bar
b && b.foo && b.foo.bar

这里的窍门是&&s 链将返回它找到的第一个false值 -并且可以将其馈送到if语句等。因此,如果b.foo是未定义的,它将返回undefined并跳过该b.foo.bar语句,而我们没有得到错误。

上面的返回值是undefined,但是如果您有一个空字符串,false,null,0,undefined,则这些值将返回,并且一旦我们在链中遇到它们[]{}它们都是“真实的”,我们将继续沿所谓的“ &&链接”到右边的下一个值。

PS做同一件事的另一种方法是(b || {}).foo,因为如果b未定义,那么b || {}它将是{},并且您将访问空对象中的值(无错误),而不是尝试访问“ undefined”中的值(导致错误) )。因此,(b || {}).foob && b.foo((b || {}).foo || {}).bar相同b && b.foo && b.foo.bar


好点-改变了我的答案。它只会在嵌套三层的对象上发生,因为就像您说的那样,它({}).anything会给您带来undefined
Ryan Taylor

5

看到所有这些很棒的答案之后,我想补充说明使用的另一个原因 !!。当前,我正在使用Angular 2-4(TypeScript),并且我希望false在用户未通过身份验证时返回一个布尔值。如果未通过身份验证,则令牌字符串将为null""。我可以通过使用下面的代码块来做到这一点:

public isAuthenticated(): boolean {
   return !!this.getToken();
}

4

这是来自angular js的一段代码

var requestAnimationFrame = $window.requestAnimationFrame ||
                                $window.webkitRequestAnimationFrame ||
                                $window.mozRequestAnimationFrame;

 var rafSupported = !!requestAnimationFrame;

他们的目的是根据requestAnimationFrame中函数的可用性将rafSupported设置为true或false

通常可以通过以下方式进行检查:

if(typeof  requestAnimationFrame === 'function')
rafSupported =true;
else
rafSupported =false;

简短的方法可能是使用!

rafSupported = !!requestAnimationFrame ;

因此,如果为requestAnimationFrame分配了一个函数,则!requestAnimationFrame将为false!这是真的

如果requestAnimationFrame的值未定义,则!requestAnimationFrame为true,还有一个!这将是错误的


3

JavaScript中的某些运算符执行隐式类型转换,有时用于类型转换。

一元运算!符将其操作数转换为布尔值并取反。

这一事实导致您可以在源代码中看到以下惯用法:

!!x // Same as Boolean(x). Note double exclamation mark


3

返回变量的布尔值。

而是Boolean可以使用class。

(请阅读代码说明)

var X = "test"; // X value is "test" as a String value
var booleanX = !!X // booleanX is `true` as a Boolean value beacuse non-empty strings evaluates as `true` in boolean
var whatIsXValueInBoolean = Boolean(X) // whatIsXValueInBoolean is `true` again
console.log(Boolean(X) === !!X) // writes `true`

Boolean(X) = !!X在使用中。

请检查下面的代码片段

let a = 0
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a) // writes '0 is NOT true in boolean' value as boolean - So that's true.In boolean 0 means false and 1 means true.
console.log("!!a: ", !!a) // writes 0 value in boolean. 0 means false.
console.log("Boolean(a): ", Boolean(a)) // equals to `!!a`
console.log("\n") // newline

a = 1
console.log("a: ", a)
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes 1 value in boolean
console.log("\n") // newline

a = ""
console.log("a: ", a)
console.log("!a: ", !a) // writes '"" is NOT true in boolean' value as boolean - So that's true.In boolean empty strings, null and undefined values mean false and if there is a string it means true.
console.log("!!a: ", !!a) // writes "" value in boolean
console.log("\n") // newline

a = "test"
console.log("a: ", a) // writes a value in its kind
console.log("!a: ", !a)
console.log("!!a: ", !!a) // writes "test" value in boolean

console.log("Boolean(a) === !!a: ", Boolean(a) === !!a) // writes true

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.