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

时间:2009-04-24 08:13:58

标签: javascript operators

我看到一些代码似乎使用了一个我无法识别的运算符,以两个感叹号的形式出现,如:!!。有人可以告诉我这个运营商做了什么吗?

我看到这个的背景是,

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

37 个答案:

答案 0 :(得分:2432)

oObject强制转换为布尔值。如果它是假的(例如0,nullundefined等),则为false,否则为true

!oObject  //Inverted boolean
!!oObject //Non inverted boolean so true boolean representation

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

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

let isIE8 = false;  
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

答案 1 :(得分:805)

进行类型转换是一种非常模糊的方式。

! NOT 。因此!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);

答案 2 :(得分:414)

!!expr会返回一个布尔值(truefalse),具体取决于表达式的真实性。在非布尔类型上使用时更有意义。请考虑这些示例,尤其是第3个示例及以后的示例:

          !!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!

答案 3 :(得分:141)

喝点茶:

!!不是运营商。它是!的两次使用 - 这是逻辑“非”运算符。


理论上:

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

  • 事实是false不是true(这就是!false结果的原因 在 true

  • 事实是true不是false(这就是!true结果的原因 在 false


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

  • 事实是true不是 true(这就是为什么!!true导致 true

  • 事实是false不是 false(这就是为什么!!false导致 false


我们希望在比较中确定的是“真相”关于引用的值,而不是引用本身的值。有一个用例,我们可能想知道关于值的真相,即使我们期望值为 false (或falsey),或者我们希望值不是是boolean的类型。


在实践中:

考虑一个简洁的功能,通过 dynamic typing (又名“鸭子打字”)检测功能功能(在这种情况下,平台兼容性)。如果用户的浏览器支持HTML5 true元素,我们想编写一个返回<audio>的函数,但如果<audio>未定义,我们不希望该函数抛出错误;我们不想使用try ... catch来处理任何可能的错误(因为它们很严重); 以及我们不希望在函数内部使用一个不能一致地揭示该特性的真相的检查(例如,document.createElement('audio')仍将创建一个名为{{1的元素即使不支持HTML5 <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 <tag>查找的参数,但它们每个都根据比较确定的值返回不同的值。

但等等,还有更多!

你们中的一些人可能已经注意到,在这个具体的例子中,人们可以使用稍微 more performant 的方法来检查属性,以检查相关对象是否具有一个属性。有两种方法可以做到这一点:

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 确实是通过使用{ {1}}。希望这可以清除它。

答案 4 :(得分:93)

!!将其右侧的值转换为其等效的布尔值。 (想想穷人的“打字”方式)。它的 intent 通常是向读者传达代码不关心变量中的值,但是"truth" value是什么。

答案 5 :(得分:65)

!!foo两次使用unary not运算符并用于强制转换为布尔类型,类似于使用一元加+foo来强制转换为数字并将空字符串''+foo连接到强制转换字符串。

您可以使用与基元类型相对应的构造函数(不使用使用new)来显式转换值,而不是这些黑客,即

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

答案 6 :(得分:59)

这么多答案做了一半的工作。是的,!!X可以被解读为&#34; X的真实性[表示为布尔值]&#34;。但是!!实际上并不是很重要,无法确定单个变量是否(或者即使很多变量都是真实的或真实的)。 !!myVar === truemyVar相同。比较!!X与&#34;真实&#34;布尔值并不是真的有用。

使用!!获得的是能够以可重复,标准化(以及JSLint友好)的方式检查多个变量相互之间的真实性

简单地施放:(

那是......

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

以上不太有用。 if (!0)为您提供与if (!!0 === false)相同的结果。我无法想到将变量转换为布尔值然后与&#34; true&#34;进行比较的好例子。布尔值。

参见&#34; ==和!=&#34;来自JSLint's directions(注意:Crockford正在移动他的网站一点点;这个链接可能会在某个时候死掉),原因如下:

  

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

     

如果您只关心某个值是真或假,那么请使用简短形式。而不是   (foo != 0)

     

只是说
  (foo)

     

而不是
  (foo == 0)

     


  (!foo)

请注意,有一些unintuitive cases,其中一个布尔值将转换为一个数字(true转换为1false转换为0)将布尔值与数字进行比较。在这种情况下,!!可能在精神上有用。虽然,再次,这些情况下,您将非布尔值与硬类型布尔值进行比较,即imo,这是一个严重的错误。 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());

由于some historical Windows jive,&#39; ll在消息框中输出-1!在cmd.exe提示符下尝试,看看!但WScript.echo(-1 == test())仍为您提供0或WScript falseLook away. It's hideous.

比较真实性:)

但是,如果我有两个值,我需要检查相同的truthi / falsi-ness怎么办?

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

  • myVar1 === myVar20 === undefined,显然是假的。
  • !!myVar1 === !!myVar2!!0 === !!undefined,是真的!同样诚实! (在这种情况下,两者都有真实性和#34;。)

所以你真正需要使用的唯一地方&#34; boolean-cast变量&#34;如果你有一个情况,你要检查两个变量是否具有相同的真实性,对吧?也就是说,使用!!如果您需要查看两个变量是是真的还是两个虚假(或不是),即相等 (或不)真实性

我无法想到一个非常好的,非人为的用例。也许你有&#34;链接&#34;表格中的字段?

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日,2月6日19:

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

这是一个有趣的案例......当第三方lib期望显式布尔值时,!!可能会有用。

例如,False in JSX (React) has a special meaning不会因简单的虚假而触发。如果您尝试在JSX中返回类似以下内容的内容,则期望messageCount中的int ...

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

...当您收到零消息时,您可能会惊讶地看到React呈现0。您必须为JSX显式返回false才能呈现。上面的语句返回0,这是JSX愉快地呈现的,应该如此。它无法告诉你没有Count: {messageCount && <div>Get your count to zero!</div>}(或者更少做作的东西)。

  • 一次修复涉及bangbang,它将0强制转换为!!0,即false
    {!!messageCount && <div>You have messages!</div>}

  • JSX&#39; docs建议你更明确,编写自我评论代码,并使用比较强制转换为布尔值 {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&amp;打字稿约定,而不是JavaScript固有的

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

答案 7 :(得分:50)

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

true === !!10

false === !!0

答案 8 :(得分:30)

它将后缀转换为布尔值。

答案 9 :(得分:24)

这是一个双not操作。第一个!将值转换为布尔值并反转其逻辑值。第二个!将逻辑值反转。

答案 10 :(得分:22)

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

答案 11 :(得分:21)

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

var foo = "Hello World!";

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

答案 12 :(得分:18)

!是“boolean not”,它基本上将“enable”的值强制转换为其布尔相反的值。第二 !翻转此值。因此,!!enable表示“不启用”,将enable的值作为布尔值。

答案 13 :(得分:17)

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

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

答案 14 :(得分:14)

!!构造是将任何JavaScript表达式转换为的简单方法 它的布尔等价物。

例如:!!"he shot me down" === true!!0 === false

答案 15 :(得分:12)

这不是一个单一的运营商,而是两个。它等同于以下内容,是一种将值转换为布尔值的快速方法。

val.enabled = !(!enable);

答案 16 :(得分:9)

!!它一起使用NOT两次操作,!将值转换为boolean并将其反转,这是一个简单的示例,可以看到{{1}工作:

首先,你有的地方:

!!

然后你做var zero = 0; ,它将被转换为布尔值并被评估为!0,因为0是true,所以你得到反转值并转换为布尔值,所以它评估为falsy

true

但是我们不想要反转布尔值的值,所以我们可以再次反转它来得到我们的结果!这就是为什么我们使用另一个!zero; //true

基本上,!让我们确定,我们获得的值是布尔值,而不是伪造,真理或字符串等......

所以就像在javascript中使用!!函数一样,但是将值转换为布尔值的简单方法更简单:

Boolean

答案 17 :(得分:9)

ifwhile语句以及?运算符使用真值来确定要运行的代码分支。例如,零和NaN数字以及空字符串为false,但其他数字和字符串为true。对象是真的,但未定义的值和null都是假的。

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

  • 如果x为假值,!xtrue!!xfalse
  • 如果x为真值,!xfalse!!xtrue

在布尔上下文(ifwhile?)的顶层使用时,!!运算符在行为上是无操作符。例如,if (x)if (!!x)意味着相同的事情。

实际用途

然而,它有几个实际用途。

一种用法是将对象有损压缩到其真值,这样您的代码就不会持有对大对象的引用并使其保持活动状态。将!!some_big_object分配给变量而不是some_big_object,可以将其用于垃圾收集器。这对于生成对象或虚假值(例如null)或未定义值(例如浏览器特征检测)的情况非常有用。

我在answer about C's corresponding !! operator中提到的另一种用法是&#34; lint&#34;寻找常见拼写错误和打印诊断的工具。例如,在C和JavaScript中,布尔运算的一些常见拼写错误产生其他行为,其输出不像布尔值:

  • if (a = b)是赋值,然后使用b的真值; if (a == b)是一种平等比较。
  • if (a & b)是一个按位AND; if (a && b)是一个逻辑AND。 2 & 50(假值); 2 && 5是真的。

!!运算符向lint工具保证你写的是你的意思:做这个操作,然后取结果的真值。

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

答案 18 :(得分:8)

我怀疑这是C ++的遗留物,人们会覆盖它!运营商,但不是bool运营商。

因此,要获得负面(或肯定)答案,您首先需要使用!运算符得到一个布尔值,但如果你想检查肯定的情况会使用!!。

答案 19 :(得分:7)

双布尔否定。通常用于检查值是否未定义。

答案 20 :(得分:7)

这里有很多很好的答案,但是如果你读到这么远的话,这有助于我“得到它”。在Chrome(等)上打开控制台,然后输入:

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

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

答案 21 :(得分:7)

!!xBoolean(x)

的简写

第一次爆炸迫使js引擎运行Boolean(x),但也有反转值的副作用。所以第二次爆炸可以解除副作用。

答案 22 :(得分:5)

重要的是要记住 JavaScript 中对 truefalse 的评估:

  • 所有带有“值”的都是true(即真实),例如:

    • 101,
    • 3.1415,
    • -11,
    • "Lucky Brain",
    • new Object()
    • 当然还有true
  • 没有“值”的一切都是false(即),例如:

    • 0,
    • -0,
    • ""(空字符串),
    • undefined,
    • null,
    • NaN(不是数字)
    • 当然还有false

应用“逻辑非”运算符 (!) 计算操作数,将其转换为 boolean,然后取反。应用它两次将否定否定,有效地将值转换为 boolean。不应用运算符将​​只是对确切值的常规分配。示例:

var value = 23; // number
var valueAsNegatedBoolean = !value; // boolean falsy (because 23 is truthy)
var valueAsBoolean = !!value; // boolean truthy
var copyOfValue = value; // number 23

var value2 = 0;
var value2AsNegatedBoolean = !value2; // boolean truthy (because 0 is falsy)
var value2AsBoolean = !!value2; // boolean falsy
var copyOfValue2 = value2; // number 0
  • value2 = value; 分配确切的对象 value,即使它不是 boolean,因此 value2 不一定最终是 boolean
  • value2 = !!value; 分配一个有保证的 boolean 作为操作数 value 的双重否定的结果,它等效于以下但更短且可读性更强:

if (value) {
  value2 = true;
} else {
  value2 = false;
}

答案 23 :(得分:5)

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

例如:

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

答案 24 :(得分: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被定义为undefined则 !requestAnimationFrame将是真的,还有一个!它会是假的

答案 25 :(得分:3)

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

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

这个事实导致您可以在源代码中看到以下习语:

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

答案 26 :(得分:3)

我只想添加

$job = $jobs->where('closing_at', '>=', Carbon::now())
        ->orderBy($sorter[0], $sorter[1])->paginate(24);

相同
if(variableThing){
  // do something
}

但是当某些事情未定义时,这可能是一个问题。

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

这里的诀窍是// a is undefined, b is empty object. 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链将返回它找到的第一个假值 - 这可以输入if语句等等。所以如果b.foo是未定义,它将返回undefined并跳过&&语句,我们没有错误。

上面的返回未定义但是如果你有一个空字符串,false,null,0,未定义这些值将返回,并且当我们在链中遇到它们时 - b.foo.bar[]都是truthy。

答案 27 :(得分:3)

在看到所有这些好的答案后,我想补充使用!!的另一个原因。当前我在Angular 2-4(TypeScript)中工作,我想在我的用户未经过身份验证时返回一个布尔值false。如果他未经过身份验证,则令牌字符串将为null""。我可以使用下一段代码来完成这项工作:

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

答案 28 :(得分:3)

返回变量的布尔值。

相反,可以使用Boolean类。

(请阅读代码说明)

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

请检查

下面的代码段

&#13;
&#13;
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
&#13;
&#13;
&#13;

答案 29 :(得分:2)

使用逻辑非运算符两次
意味着!true = false
 和!! !! true = true

答案 30 :(得分:2)

!!类似于使用Boolean constructor,或者更像是Boolean function.

&#13;
&#13;
console.log(Boolean(null)); // Preffered over the Boolean object

console.log(new Boolean(null).valueOf()); // Not recommended for coverting non-boolean values

console.log(!!null); // A hacky way to omit calling the Boolean function, but essentially does the same thing. 


// The context you saw earlier (your example)
var vertical;

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical; 
        // Let's break it down: If vertical is strictly not undefined, return the boolean value of vertical and set it to this.vertical. If not, don't set a value for this.vertical (just ignore it and set it back to what it was before; in this case, nothing).   

        return this.vertical;
}

console.log( "\n---------------------" )

// vertical is currently undefined

console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = 12.5; // set vertical to 12.5, a truthy value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be true anyway
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical

vertical = -0; // set vertical to -0, a falsey value.
console.log(new Example(vertical).vertical); // The falsey or truthy value of this.vertical which happens to be false either way
console.log(!!new Example(vertical).vertical); // Coerced value of this.vertical
&#13;
&#13;
&#13;

虚假值在javascript 强制 false truthy值 强制 true。 Falsey和truthy值也可以在if语句中使用,并且基本上是&#34; map&#34;到它们相应的布尔值。但是,您可能不会经常发现自己必须使用正确的布尔值,因为它们的输出(返回值)大多不同。

  

虽然这可能看起来与投射类似,但实际上这可能只是仅仅巧合并且没有“建造”#39;或故意为布尔演员而制作。所以,我们不要这么称呼它。

为什么以及如何运作

简而言之,它看起来像这样:! ( !null )。鉴于null falsey ,因此!null为真。那么!true将是 false ,它基本上会反转到之前的状态, 除了这次作为适当的布尔值(或者甚至反之亦然,其中 truthy值,如{}1) 。


回到你的例子

总体而言,您看到的上下文只是根据this.vertical是否已定义来调整vertical,如果是,它将被设置为垂直的结果布尔值,否则它将不会改变。换句话说,如果定义了vertical; this.vertical将被设置为它的布尔值,否则它将保持不变。我想这本身就是你如何使用!!及其作用的一个例子。


垂直I / O示例

运行此示例并使用输入中的垂直值进行调整。查看结果所强制的内容,以便您可以完全理解上下文的代码。在输入中,输入任何有效的javascript值。 如果您要测试字符串,请记住要包含引号。请不要过多考虑CSS和HTML代码,只需运行此代码段并使用它即可。但是,您可能希望查看非DOM相关的javascript代码(使用Example构造函数和垂直变量)。

&#13;
&#13;
var vertical = document.getElementById("vertical");
var p = document.getElementById("result");

function Example(vertical)
{
        this.vertical = vertical !== undefined ? !!vertical : 
        this.vertical;   

        return this.vertical;
}

document.getElementById("run").onclick = function()
{

  p.innerHTML = !!( new Example(eval(vertical.value)).vertical );
  
}
&#13;
input
{
  text-align: center;
  width: 5em;
} 

button 
{
  margin: 15.5px;
  width: 14em;
  height: 3.4em;
  color: blue;
}

var 
{
  color: purple;
}

p {
  margin: 15px;
}

span.comment {
  color: brown;
}
&#13;
<!--Vertical I/O Example-->
<h4>Vertical Example</h4>
<code id="code"><var class="var">var</var> vertical = <input type="text" id="vertical" maxlength="9" />; <span class="comment">// enter any valid javascript value</span></code>
<br />
<button id="run">Run</button>
<p id="result">...</p>
&#13;
&#13;
&#13;

答案 31 :(得分:2)

a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined

对于!a,它会检查a是否 NOT ,而!!a检查变量是否已定义。

!!a!(!a)相同。如果定义了a,则atrue!afalse!!atrue

答案 32 :(得分:2)

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

因为javascript具有所谓的“真值”和“假值”,所以有些表达式在其他表达式中求值时会得出真假条件,即使所检查的值或表达式实际上不是{{1 }}或RewriteEngine on RewriteRule !website/app /website/app℅{REQUEST_URI} [L]

例如:

true

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

但是:

false

...将不会导致结果为真,即使该元素确实存在,也不会执行代码块。

为什么?因为if (document.getElementById('myElement')) { // code block } 是一个“真实的”表达式,在此if (document.getElementById('myElement') == true) { // code block } 语句中将被评估为true,但它不是document.getElementById()的实际布尔值。

在这种情况下,双“ not”非常简单。只是两个if()背对背。

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

true

not

两者将按预期返回true。

答案 33 :(得分:0)

双精度将变量评估为布尔值。例如:假 0(零),“''或“”(空字符串),null,未定义,NaN计算为false。 参见此帖子https://www.sitepoint.com/javascript-truthy-falsy/

答案 34 :(得分:0)

要将JavaScript变量转换为布尔值,

var firstname = "test";
//type of firstname is string
var firstNameNotEmpty = !!firstname;
//type of firstNameNotEmpty is boolean

javascript false 表示“”,0,未定义和空值

javascript为 true ,表示除零以外的其他数字,不是空字符串,{},[]和新的Date() 所以,

!!("test") /*is true*/
!!("") /*is false*/

答案 35 :(得分:0)

const foo = 'bar';
console.log(!!foo); // Boolean: true

!取反(取反)一个值,并且总是返回/产生一个布尔值。所以!'bar'会产生false(因为'bar'是true =>否定+ boolean = false)。随着附加!运算符,该值将再次取反,因此false变为true。

答案 36 :(得分:-3)

这是检查undefined,“undefined”,null,“null”,“”

的非常方便的方法
if (!!var1 && !!var2 && !!var3 && !!var4 ){
   //... some code here
}