我看到一些代码似乎使用了我不认识的运算符,以两个感叹号的形式出现,如下所示:!!
. 有人可以告诉我这个操作员是做什么的吗?
我看到这个的背景是,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
我看到一些代码似乎使用了我不认识的运算符,以两个感叹号的形式出现,如下所示:!!
. 有人可以告诉我这个操作员是做什么的吗?
我看到这个的背景是,
this.vertical = vertical !== undefined ? !!vertical : this.vertical;
转换Object
为boolean
. 如果它是假的(例如,,,0
等null
)undefined
,它将是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
如果你⇒</p>
console.log(navigator.userAgent.match(/MSIE 8.0/));
// returns either an Array or null
但是如果你⇒</p>
console.log(!!navigator.userAgent.match(/MSIE 8.0/));
// returns either true or false
这是进行类型转换的一种非常晦涩的方法。
!
表示不。如此,如此。!true
_ 是,并且是。false
!false
true
!0
true
!1
false
因此,您将一个值转换为布尔值,然后将其反转,然后再次反转它。
// Maximum Obscurity:
val.enabled = !!userId;
// Partial Obscurity:
val.enabled = (userId != 0) ? true : false;
// And finally, much easier to understand:
val.enabled = (userId != 0);
!!expr
(两个!
运算符后跟一个表达式)根据表达式的真实性true
返回一个布尔值(或) 。在非布尔类型上使用时更有意义。考虑这些示例,尤其是第三个示例及以后的示例:false
!!false === false
!!true === true
!!0 === false
!!parseInt("foo") === false // NaN is falsy
!!1 === true
!!-1 === true // -1 is truthy
!!(1/0) === true // Infinity 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 value is falsy
!!undefined === false // undefined primitive is falsy
!!null === false // null is falsy
!!{} === true // an (empty) object is truthy
!![] === true // an (empty) array is truthy; PHP programmers beware!
泡茶:
!!
不是运算符。它是!
-- 的双重用途,它是逻辑“非”运算符。
理论上:
!
确定值不是什么的“真相”:
事实是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
从非布尔值、可能未定义的值获取的方法确实是使用!!
. 希望这可笑地清除它。
!!
将其右侧的值转换为其等效的布尔值。(想想穷人的“类型转换”方式)。它的意图通常是向读者传达代码并不关心变量中的值是什么,而是它的“真实”值是什么。
!!foo
应用一元非运算符两次,用于转换为布尔类型,类似于使用一元加号+foo
转换为数字并连接空字符串''+foo
以转换为字符串。
除了这些技巧,您还可以使用与原始类型对应的构造函数(不使用new
)来显式转换值,即
Boolean(foo) === !!foo
Number(foo) === +foo
String(foo) === ''+foo
这么多答案做了一半的工作。是的,!!X
可以理解为“X [表示为布尔值] 的真实性”。但是!!
,实际上,对于确定单个变量是(或者即使许多变量是)真还是假来说,这并不是那么重要。!!myVar === true
和刚才一样myVar
。与!!X
“真正的”布尔值相比并不是很有用。
您获得的唯一好处是能够以可重复的、标准化的(和 JSLint 友好的)方式!!
检查多个变量的真实性。
那是...
0 === false
是false
。!!0 === false
是true
。上面的用处不大。if (!0)
给你同样的结果if (!!0 === false)
。我想不出将变量转换为布尔值然后与“真实”布尔值进行比较的好案例。
请参阅JSLint 的指示中的“== 和!=” (注意:Crockford 正在稍微移动他的网站;该链接可能会在某个时候失效)以了解原因:
== 和 != 运算符在比较之前进行强制类型转换。这很糟糕,因为它会导致 ' \t\r\n' == 0 为真。这可以掩盖类型错误。JSLint 无法可靠地确定 == 是否被正确使用,因此最好不要使用 == 和 != 并始终使用更可靠的 === 和 !== 运算符。
如果你只关心一个值是真还是假,那么使用简写形式。代替
(foo != 0)
说啊
(foo)
而不是
(foo == 0)
说
(!foo)
请注意,在将布尔值与数字进行比较时,存在一些不直观的情况,即布尔值将被强制转换为数字(true
被强制转换为1
和false
to 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());
由于某些历史悠久的 Windows jive,这将在消息框中输出 -1 !在 cmd.exe 提示符下试试看!但WScript.echo(-1 == test())
仍然给你 0,或 WScript 的false
. 移开视线。太可怕了
但是,如果我有两个值需要检查相等的真/假怎么办?
假设我们有myVar1 = 0;
和myVar2 = undefined;
。
myVar1 === myVar2
是0 === undefined
而且显然是错误的。!!myVar1 === !!myVar2
是!!0 === !!undefined
而且是真的!一样的真实!(在这种情况下,两者都“具有虚假的真实性”。)因此,您真正需要使用“布尔转换变量”的唯一地方是,如果您遇到一种情况,即检查两个变量是否具有相同的真实性,对吧?也就是说,如果您需要查看两个 vars 是否都为真或都为假(或不是),即相等(或不)真值,请使用。!!
我想不出一个伟大的、非人为的用例来做这个副手。也许您在表单中有“链接”字段?
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 日:
这是一个有趣的案例......!!
当第 3 方库需要明确的布尔值时可能很有用。
例如,JSX (React) 中的 False 有一个特殊的含义,它不会因简单的虚假而触发。如果您尝试在 JSX 中返回类似以下内容,则期待 int in messageCount
...
{messageCount && <div>You have messages!</div>}
0
...当您有零消息时,您可能会惊讶地看到 React 渲染 a 。您必须显式返回 false 才能使 JSX 不呈现。上面的语句返回0
,JSX 会愉快地呈现它,就像它应该的那样。它不能告诉你没有Count: {messageCount}
。
一种解决方法涉及 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 中的相同处理:如果您有一个返回布尔值的函数(或者您正在为布尔变量分配一个值),那么您 [通常] 不能返回/分配一个 boolean-y 值;它必须是强类型的布尔值。这意味着,iffmyObject
是强类型的,return !myObject;
适用于返回布尔值的函数,但return myObject;
不是。您必须return !!myObject
(或以另一种方式转换为正确的布尔值)才能匹配 Typescript 的期望。
Typescript 的例外?如果
myObject
是any
,那么您就回到了 JavaScript 的狂野西部,并且可以在没有 的情况下返回它!!
,即使您的返回类型是布尔值。
请记住,这些是 JSX 和 Typescript 约定,而不是 JavaScript 固有的约定。
但是,如果您0
在渲染的 JSX 中看到奇怪的 s,请考虑松散的虚假管理。
它只是逻辑 NOT 运算符,两次 - 它用于将某些内容转换为布尔值,例如:
true === !!10
false === !!0
它将后缀转换为布尔值。
这是一个双重not
操作。第一个!
将值转换为布尔值并反转其逻辑值。第二个!
反转逻辑值。
似乎!!
运算符导致双重否定。
var foo = "Hello World!";
!foo // Result: false
!!foo // Result: true
它模拟了Boolean()
强制转换函数的行为。NOT
无论给出什么操作数,第一个都返回一个布尔值。第二个NOT
否定该Boolean
值,因此给出true
变量的布尔值。Boolean()
最终结果与对值使用函数相同。
!!
它NOT
一起使用操作两次,!
将值转换为 aboolean
并将其反转,因此使用它两次,显示该值的布尔值(假或真)。这是一个简单的例子,看看它是如何!!
工作的:
首先,你有的地方:
var zero = 0;
然后你这样做!0
,它将被转换为布尔值并被评估为true
,因为 0 是falsy
,所以你得到反转的值并转换为布尔值,所以它被评估为true
。
!zero; //true
但是我们不想要反转的布尔版本的值,所以我们可以再次反转它来得到我们的结果!这就是为什么我们使用另一个!
.
基本上,!!
请确保我们得到的值是布尔值,而不是虚假、真实或字符串等......
所以这就像Boolean
在 javascript 中使用函数,但是将值转换为布尔值的简单而短的方法:
var zero = 0;
!!zero; //false
!是“布尔非”,它本质上将“启用”的值类型转换为其布尔值的对立面。第二 !翻转这个值。因此,!!enable
意味着“不启用”,为您enable
提供布尔值。
我认为值得一提的是,与逻辑 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
这不是一个操作员,而是两个。它等效于以下内容,是一种将值转换为布尔值的快速方法。
val.enabled = !(!enable);
该!!
构造是将任何 JavaScript 表达式转换为其布尔等效项的简单方法。
例如:!!"he shot me down" === true
和!!0 === false
。
这个问题已经得到了相当彻底的回答,但我想补充一个我希望尽可能简化的答案,使 !! 尽可能简单地掌握。
因为 javascript 具有所谓的“真”和“假”值,所以有些表达式在其他表达式中求值时会产生真或假条件,即使被检查的值或表达式实际上不是true
or false
。
例如:
if (document.getElementById('myElement')) {
// code block
}
如果该元素确实存在,则表达式将评估为真,并且将执行代码块。
然而:
if (document.getElementById('myElement') == true) {
// code block
}
...不会产生真条件,并且即使元素确实存在,代码块也不会被执行。
为什么?因为document.getElementById()
是一个“真实”的表达式,将在此if()
语句中评估为真,但它不是true
.
在这种情况下,双重“不”非常简单。它只是两个not
背靠背。
第一个简单地“反转”真值或假值,产生一个实际的布尔类型,然后第二个“反转”它再次回到它的原始状态,但现在是一个实际的布尔值。这样你就有了一致性:
if (!!document.getElementById('myElement')) {}
和
if (!!document.getElementById('myElement') == true) {}
正如预期的那样,两者都会返回true。
我怀疑这是 C++ 的遗留物,人们会覆盖 ! 运算符,但不是布尔运算符。
因此,在这种情况下,要获得否定(或肯定)答案,您首先需要使用 ! 运算符获取布尔值,但如果您想检查肯定的情况,请使用 !!。
if
andwhile
语句和?
运算符使用真值来确定要运行的代码分支。例如,零和 NaN 数字和空字符串为假,但其他数字和字符串为真。对象为真,但未定义的值和null
都为假。
双重否定运算符!!
计算一个值的真值。它实际上是两个运算符,其中的!!x
意思是!(!x)
,并且行为如下:
x
是假值,!x
是true
,!!x
是false
。x
是一个真值,!x
是false
,并且!!x
是true
。if
当在布尔上下文( 、while
或?
)的顶层使用时,!!
运算符在行为上是无操作的。例如,if (x)
和if (!!x)
意思是一样的。
然而,它有几个实际用途。
一种用途是将对象有损地压缩为其真值,这样您的代码就不会持有对大对象的引用并使其保持活动状态。分配!!some_big_object
给一个变量而不是some_big_object
让垃圾收集器放弃它。这对于产生对象或错误值(例如null
或未定义值)的情况很有用,例如浏览器功能检测。
我在关于 C 的相应!!
operator的回答中提到的另一个用途是使用“lint”工具来查找常见的拼写错误和打印诊断。例如,在 C 和 JavaScript 中,布尔运算的一些常见拼写错误会产生其他行为,其输出与布尔运算不同:
if (a = b)
是赋值,然后使用 的真值b
;if (a == b)
是相等比较。if (a & b)
是按位与;if (a && b)
是逻辑与。2 & 5
是0
(假值);2 && 5
是真的。!!
操作员向 lint 工具保证你写的就是你的意思:做这个操作,然后取结果的真值。
第三种用途是产生逻辑 XOR 和逻辑 XNOR。在 C 和 JavaScript 中,a && b
执行逻辑与(如果双方都为真,则为真),并a & b
执行按位与。a || b
执行逻辑或(如果至少有一个为真,则为真),并a | b
执行按位或。有一个按位异或(异或)作为a ^ b
,但没有用于逻辑异或的内置运算符(如果恰好一侧为真,则为真)。例如,您可能希望允许用户在两个字段之一中输入文本。您可以做的是将每个转换为真值并进行比较:!!x !== !!y
.
双布尔否定。通常用于检查值是否未定义。
!!x
是简写Boolean(x)
第一个 bang 强制 js 引擎运行Boolean(x)
,但也有反转值的副作用。所以第二次爆炸消除了副作用。
我只是想补充一点
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 是未定义的,它将返回未定义并跳过该b.foo.bar
语句,我们得到 no错误。
上面的返回 undefined 但如果你有一个空字符串,false, null, 0, undefined 这些值将返回,并且一旦我们在链中遇到它们——[]
并且{}
都是“真实的”,我们将继续所谓的“ && 链”到右边的下一个值。
PS执行上述 ( b && b.foo
) 的另一种方法是(b || {}).foo
. 这些是等价的,因为如果 b 未定义,b || {}
则将是{}
,并且您将访问空对象中的值(无错误),而不是尝试访问“未定义”中的值(导致错误)。
所以,(b || {}).foo
与 相同,b && b.foo
与((b || {}).foo || {}).bar
相同b && b.foo && b.foo.bar
。
它强制所有东西都是布尔值。
例如:
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
这里有很多很好的答案,但如果你已经读到这里,这有助于我“明白”。在 Chrome(等)上打开控制台,然后开始输入:
!(!(1))
!(!(0))
!(!('truthy'))
!(!(null))
!(!(''))
!(!(undefined))
!(!(new Object())
!(!({}))
woo = 'hoo'
!(!(woo))
...etc, etc, until the light goes on ;)
当然,这些都与仅键入 !!someThing 相同,但添加的括号可能有助于使其更易于理解。
在看到所有这些很棒的答案之后,我想添加另一个使用 !!
. 目前我正在使用 Angular 2-4 (TypeScript),我想false
在我的用户未通过身份验证时返回一个布尔值。如果他未通过身份验证,则令牌字符串将为null
or ""
。我可以通过使用下一个代码块来做到这一点:
public isAuthenticated(): boolean {
return !!this.getToken();
}
这是来自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 = false
和 !!true = true
记住对JavaScripttrue
的评估很重要:false
具有“价值”的一切都是true
(即真),例如:
101
,3.1415
,-11
,"Lucky Brain"
,new Object()
true
没有“价值”的一切都是false
(即falsy),例如:
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;
}
JavaScript 中的一些运算符执行隐式类型转换,有时用于类型转换。
一元运算!
符将其操作数转换为布尔值并将其取反。
这一事实导致您可以在源代码中看到以下成语:
!!x // Same as Boolean(x). Note double exclamation mark
要将 JavaScript 变量转换为布尔值,
var firstname = "test";
//type of firstname is string
var firstNameNotEmpty = !!firstname;
//type of firstNameNotEmpty is boolean
javascript false for "",0,undefined and null
javascript适用于除零以外的数字,而不是空字符串、{}、[] 和 new Date() 所以,
!!("test") /*is true*/
!!("") /*is false*/
a = 1;
alert(!a) // -> false : a is not not defined
alert(!!a) // -> true : a is not not defined
对于!a
,它检查是否a
未定义,同时!!a
检查变量是否已定义。
!!a
是一样的!(!a)
。如果a
定义,a
是true
,!a
是false
,!!a
是true
。
console.log(Boolean(null)); // Preferred 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
javascript 中的Falsey 值强制为false,而真值 强制为true 。假值和真值也可以在if
语句中使用,并且本质上将“映射”到它们相应的布尔值。但是,您可能不会发现自己必须经常使用正确的布尔值,因为它们的输出(返回值)大多不同。
尽管这可能看起来类似于强制转换,但实际上这可能仅仅是巧合,并不是“构建”或特意为布尔类型转换而制造的。所以我们不要这样称呼它。
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 );
}
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;
}
<!--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>
有时需要检查我们在函数中是否有值,数量本身对我们来说并不重要,而是它是否重要。例如,我们要检查用户是否有专业,我们有一个功能,就像:
hasMajor(){return this.major}//it return "(users major is)Science"
但答案对我们来说并不重要,我们只想检查它是否有专业,我们需要一个布尔值(真或假)我们如何得到它:
像这样:
hasMajor(){ return !(!this.major)}
或同样
hasMajor(){return !!this.major)}
如果 this.major 有一个值,则!this.major
返回 false,但是因为该值已经退出,我们需要返回 true,我们使用 ! 两次返回正确答案!(!this.major)
const foo = 'bar';
console.log(!!foo); // Boolean: true
!否定(反转)一个值并且总是返回/产生一个布尔值。所以 !'bar' 会产生 false (因为 'bar' 是真的 => 否定 + boolean = false)。随着额外的!运算符,该值再次被否定,因此 false 变为 true。
!!不是运算符,它只是 ! 操作员两次
但是使用javascript,应用!在大多数情况下,将 Object 转换为布尔值是冗余和冗长的,因为:
值不是 undefined 或 null 的任何对象,包括值为 false 的布尔对象,在传递给条件语句时评估为 true
前任: if ({}) { console.log("{} is true")} // logs: "{} is true"
这是检查未定义、“未定义”、“空”、“空”、“”的一种非常方便的方法
if (!!var1 && !!var2 && !!var3 && !!var4 ){
//... some code here
}