อะไรคือ !! (ไม่ใช่) โอเปอเรเตอร์ใน JavaScript หรือไม่


3105

!!ผมเห็นรหัสบางอย่างที่ดูเหมือนว่าจะใช้ผู้ประกอบการที่ฉันไม่รู้จักในรูปแบบของสองจุดอัศเจรีย์เช่นดังนั้น: ใครช่วยบอกฉันทีว่าผู้ให้บริการรายนี้ทำอะไร

บริบทที่ฉันเห็นสิ่งนี้คือ

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

944
จำได้ว่ามันด้วย "ปังปังคุณบูลกำลัง"
กัส

75
เพียงบันทึกอย่าทำสิ่งที่ยกมามี ทำif(vertical !== undefined) this.vertical = Boolean(vertical);- มันเป็นทำความสะอาดมากและชัดเจนสิ่งที่เกิดขึ้นไม่จำเป็นต้องมีการกำหนดที่ไม่จำเป็นเป็นมาตรฐานทั้งหมดและเป็นเพียงความรวดเร็ว (บน FF ปัจจุบันและ Chrome) jsperf.com/boolean-conversion-speed
Phil H

73
!! ไม่ใช่ผู้ประกอบการ มันเป็นเพียง! ผู้ประกอบการสองครั้ง
Vivek

11
เพียงเพื่อบันทึกBoolean(5/0)ไม่เหมือนกับ!!5/0
schabluk

63
@schabluk สำหรับบันทึก, การดำเนินงานเพื่อเป็นเหตุผลที่!!5/0ผลิตInfinityมากกว่าเป็นที่ผลิตโดยtrue เทียบเท่ากับ- aka - เนื่องจากผู้ประกอบการที่มีความสำคัญสูงกว่าผู้ประกอบการ หากคุณต้องการที่จะ Booleanize ใช้คู่ปัง, คุณจะต้องใช้ Boolean(5/0)!!5/0(!!5)/0true/0!/5/0!!(5/0)
matty

คำตอบ:


2745

แปลงไปObject booleanถ้ามันเป็น falsey (เช่น0, null, undefinedฯลฯ ) มันจะเป็นอย่างอื่นfalsetrue

!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
มันแปลง nonboolean เป็นบูลีนแบบ inverted (ตัวอย่างเช่น! 5 จะเป็นเท็จเนื่องจาก 5 เป็นค่าที่ไม่เป็นเท็จใน JS) จากนั้นบูลีน - กลับด้านที่คุณจะได้รับค่าเดิมเป็นบูลีน (ดังนั้น !! 5 เป็นจริง)
Chuck

111
วิธีง่าย ๆ ในการอธิบายคือ: บูลีน (5) === !! 5; การคัดเลือกนักแสดงเดียวกันตัวละครน้อยลง
คาห์ไนเดอร์

39
สิ่งนี้ใช้เพื่อแปลงค่าความจริงเป็นบูลีนจริงและค่าเท็จเป็นบูลีนเท็จเกินไป
thetoolman

13
@Micah Snyder โปรดระวังว่าใน JavaScript จะเป็นการดีกว่าถ้าใช้บูลีนแบบดั้งเดิมแทนการสร้างวัตถุที่กล่องบูลีนด้วย Boolean ใหม่ () นี่คือตัวอย่างเพื่อดูความแตกต่าง: jsfiddle.net/eekbu
victorvartan

4
เท่าที่ฉันทราบรูปแบบการระเบิดของปังปังนี้ไม่มีประโยชน์ในคำสั่ง if (… _ เฉพาะในคำสั่ง return ของฟังก์ชันที่ควรคืนค่าบูลีน
rds

854

มันเป็นวิธีที่คลุมเครืออย่างน่ากลัวในการแปลงประเภท

!คือไม่ ดังนั้น!trueเป็นfalseและเป็น!false เป็นและเป็นtrue!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);

74
!! false = false !! true = true
cllpse

89
ตัวแปร "เข้าใจง่ายกว่า" เข้าใจง่ายกว่าหรือไม่ การตรวจสอบกับ 0 ไม่ใช่การตรวจสอบจริงกับ 0 แต่การตรวจสอบกับรายการที่ค่อนข้างแปลก Javascript พิจารณาเท่ากับ 0 userId ? true : false ทำให้ชัดเจนมากขึ้นว่ามีการแปลงเกิดขึ้นและจัดการกรณีที่ค่าของ userId อาจถูกตั้งค่าอย่างชัดเจนundefined
Ben Regenspan

54
สมองของฉันไม่ได้มีปัญหาใด ๆ ถอดรหัส!!varเข้าไปBoolean(var).. และ!!จะเร็ว (คำสั่งน้อยที่จะดำเนินการ) และสั้นกว่าทางเลือก
adamJLev

7
@RickyClarkson ส่วนใหญ่มีไว้เพื่อให้สามารถอ่านได้เนื่องจากไม่มีความจำเป็นในการสร้างประโยค บางคนใช้การประชุมเพื่อห่อเงื่อนไขไว้ในวงเล็บเสมอเพื่อตั้งค่าให้แตกต่างจากนิพจน์ที่เหลือ
Dave Rager

8
ฉันไม่เห็นด้วยกับสิ่งนี้ userId != 0เป็นจริงสำหรับnull, NaNและแต่เท็จundefined falseหากคุณต้องการพฤติกรรมที่แน่นอนคุณอาจต้องมีความชัดเจน แต่แม้ว่ามันจะทำงานได้ตรงเหมือนกัน!!userIdแต่ก็ยังไม่ชัดเจนว่าคุณต้องการให้ค่าเหล่านั้นเป็นเท็จที่นี่หรือไม่หรือคุณเพียงแค่ไม่สามารถพิจารณากฎการแปลงประเภทของ Javascript
philh

449

!!exprส่งกลับค่าบูลีน ( trueหรือfalse) ขึ้นอยู่กับtruthinessของการแสดงออก มันสมเหตุสมผลมากกว่าเมื่อใช้กับชนิดที่ไม่ใช่บูลีน ลองพิจารณาตัวอย่างเหล่านี้โดยเฉพาะตัวอย่างที่ 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!

63
เร็ว ๆ นี้:!!new Boolean(false) // true
Camilo Martin

43
... แต่ยังมี!!Boolean(false) // false
Camilo Martin

97
new Boolean(false)เป็นวัตถุและวัตถุมีความจริงแม้ว่ามันจะมีค่าที่ผิดพลาด!
Salman

3
ใช่ฉันรู้ แต่พิจารณาข้อเท็จจริงที่ว่าก่อสร้างพื้นเมืองส่วนใหญ่ ( String, Number, Dateฯลฯ ) จะหมายถึงการ callable เป็นฟังก์ชั่นมากเกินไป แต่ในกรณีนี้ผลที่ได้คือแตกต่างกัน!
Camilo Martin

4
@CamiloMartin: เพียงแค่ตระหนักว่าnew Boolean(false)ส่งกลับobjectในขณะที่Boolean(false)ผลตอบแทนดั้งเดิม falseหวังว่ามันจะสมเหตุสมผล
Salman

155

ชงชา:

!!ไม่ใช่ผู้ประกอบการ มันคือการใช้สองครั้ง!- ซึ่งเป็นตัวดำเนินการตรรกะ "ไม่"


ในทางทฤษฎี:

! กำหนด "ความจริง" ของสิ่งที่มีค่าไม่ใช่:

  • ความจริงก็falseคือไม่ใช่true(นั่นเป็นสาเหตุที่!falseทำให้เกิดผลลัพธ์true)

  • ความจริงก็trueคือไม่ใช่false(นั่นเป็นสาเหตุที่!trueทำให้เกิดผลลัพธ์false)


!!กำหนด "ความจริง" ของสิ่งที่เป็นค่าที่ไม่ได้:

  • ความจริงก็คือtrueมันไม่ได้เป็น true (นั่นคือเหตุผลที่!!trueผลในtrue)

  • ความจริงก็คือfalseมันไม่ได้เป็น false (นั่นคือเหตุผลที่!!falseผลในfalse)


สิ่งที่เราต้องการตรวจสอบในการเปรียบเทียบคือ "ความจริง" เกี่ยวกับมูลค่าของการอ้างอิงไม่ใช่มูลค่าของการอ้างอิง มีการใช้งานในกรณีที่เราอาจจะต้องการทราบความจริงเกี่ยวกับค่าคือแม้ว่าเราคาดว่าค่าเป็นfalse(หรือ falsey) หรือหากเราคาดว่าค่าไม่ได้ที่จะ booleantypeof


ในทางปฏิบัติ:

พิจารณาฟังก์ชั่นรัดกุมซึ่งตรวจจับการทำงานของคุณสมบัติ (และในกรณีนี้ความเข้ากันได้ของแพลตฟอร์ม) โดยวิธีการพิมพ์แบบไดนามิก (aka "การพิมพ์เป็ด") เราต้องการเขียนฟังก์ชั่นที่ส่งคืนtrueหากเบราว์เซอร์ของผู้ใช้รองรับ<audio>องค์ประกอบHTML5 แต่เราไม่ต้องการให้ฟังก์ชันส่งข้อผิดพลาดหาก<audio>ไม่ได้กำหนดไว้ และเราไม่ต้องการใช้try ... catchเพื่อจัดการข้อผิดพลาดที่เป็นไปได้ และเราไม่ต้องการใช้การตรวจสอบภายในฟังก์ชั่นที่จะไม่เปิดเผยความจริงเกี่ยวกับคุณสมบัติ (ตัวอย่างเช่นdocument.createElement('audio')จะยังคงสร้างองค์ประกอบที่เรียกว่า<audio>แม้ว่า<audio>จะไม่รองรับHTML5 )


นี่คือสามวิธี:

// 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>และa 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

เราเชือนแช ...

แต่หายากสถานการณ์เหล่านี้อาจจะมีสถานการณ์ที่อาจมีอยู่ไม่กี่ที่รัดกุมที่สุด performant มากที่สุดและทำให้ที่ต้องการมากที่สุดหมายถึงการได้รับtrueจาก !!non-บูลค่าอาจจะไม่ได้กำหนดแน่นอนโดยใช้ หวังว่านี่จะเป็นการลบล้างมันอย่างน่าขัน


1
คำตอบที่ยอดเยี่ยมโดยสิ้นเชิง แต่ฉันไม่เห็นอรรถประโยชน์ของ !! สร้าง. เนื่องจากif()คำแถลงที่แสดงออกมาเป็นบูลีนแล้วการส่งคืนค่าของฟังก์ชั่นการทดสอบเพื่อบูลียอย่างชัดเจนนั้นซ้ำซ้อน - เนื่องจาก "ความจริง" === จริงตามif()คำแถลงต่อไป หรือว่าฉันพลาดสถานการณ์ที่คุณต้องการแสดงออกถึงความจริงว่าเป็นบูลีนจริงtrueหรือ
Tom Auger

1
if()คำสั่ง@TomAuger จะใช้บูลีนเทียบกับค่าเท็จ แต่บอกว่าคุณต้องการตั้งค่าสถานะบูลีนบนวัตถุจริง ๆ แล้วมันจะไม่ส่งผลเหมือนที่if()คำสั่งทำ ตัวอย่างเช่นobject.hasTheThing = !!castTheReturnValToBoolNoMatterWhat()จะตั้งค่าอย่างใดอย่างหนึ่งtrueหรือfalseแทนค่าผลตอบแทนที่แท้จริง อีกตัวอย่างหนึ่งคือผู้ดูแลระบบทั้งหมดเป็นidของ0และผู้ดูแลระบบไม่ใช่ id 1หรือสูงกว่า เพื่อให้ได้ถ้ามีคนไม่ได้เป็นผู้ดูแลระบบที่คุณสามารถทำได้true person.isNotAdmin = !!admin.idใช้น้อยราย แต่ก็กระชับเมื่อมี
Benny

103

!!แปลงค่าทางด้านขวาของมันเป็นค่าบูลีนที่เทียบเท่า (คิดว่าวิธีการหล่อแบบคนจนของคนจน) ความตั้งใจของมันคือเพื่อถ่ายทอดให้ผู้อ่านทราบว่าโค้ดไม่สนใจสิ่งที่มีค่าในตัวแปร แต่สิ่งที่เป็นค่า "ความจริง"คืออะไร


4
หรือในกรณีของค่าบูลีนทางด้านขวามันไม่ทำอะไรเลย
Daniel A. White

3
@Daniel: !ยังคงพลิกค่าไปทางขวา ในกรณีของบูลีนจะเป็นการ!ลบล้างค่าที่ถูกต้องที่สุดในขณะที่!แบ็กซ้ายจะลบล้างค่านั้นอีกครั้ง ผลกระทบสุทธิคือไม่มีการเปลี่ยนแปลง แต่เครื่องมือส่วนใหญ่จะสร้างรหัส op สำหรับการปฏิเสธคู่
Crescent Fresh

แต่ประเด็นคืออะไร? ถ้าฉันทำif(0){...Javascript รู้อยู่แล้วว่านี่เป็นเท็จ ทำไมจะดีกว่าที่จะพูดif(!!0){...?
CodyBugstein

จุดสำหรับตัวแปรที่คุณอาจไม่รู้เนื้อหา ถ้ามันอาจเป็นจำนวนเต็มหรือสตริงวัตถุหรือโมฆะไม่ได้กำหนด ฯลฯ นี่เป็นวิธีที่ง่ายในการทดสอบการมีอยู่
mix3d

71

!!fooใช้ตัวดำเนินการ unary not สองครั้งและถูกใช้เพื่อส่งไปยังประเภทบูลีนคล้ายกับการใช้งานของ unary plus +fooเพื่อส่งไปยังหมายเลขและเชื่อมสตริงที่ว่างเปล่า''+fooเข้ากับสตริง

แทนที่จะเป็นแฮ็กเหล่านี้คุณยังสามารถใช้ฟังก์ชั่นคอนสตรัคที่สอดคล้องกับประเภทดั้งเดิม ( โดยไม่ต้องใช้new) ในการคำนวณค่าเช่น

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

แต่คุณสามารถพบปัญหากับอินสแตนซ์ของ ใหม่ Boolean (1) instanceof Object -> true !! 1 instanceof Object -> false
Seamus

13
ไม่คุณไม่สามารถสังเกตได้ว่าฟังก์ชั่นคอนสตรัคเตอร์ถูกเรียกโดยไม่ต้องnew- ดังที่ได้กล่าวไว้อย่างชัดเจนในคำตอบของฉัน
Christoph

2
! ที่ยอดเยี่ยม สิ่งนี้มีประโยชน์สำหรับการแฮ็กเล็กน้อยเมื่อคุณต้องการประเมินสตริงด้วย "0" เป็นเท็จแทนที่จะเป็นจริง (เช่นเมื่ออ่านค่าจากการเลือกเพราะพวกเขาอ่านเป็นสตริง) ดังนั้นหากคุณต้องการพิจารณาว่า "0" เป็นลบ (Boolean false), asuming x="0"เพียงทำ: x=!!+x; //falseซึ่งเหมือนกับBoolean(Number(x))Number (หรือ + x) แปลงสตริง "0" เป็น 0 ซึ่งจะประเมินเป็นเท็จแล้ว Boolean (!! x) ปลดมันเพื่อบูลีนโดยตรง peasy ง่าย ๆ !
DiegoDD

2
@DiegoDD เหตุผลที่คุณจะเลือก!!+xVS x !== "0"?
placeybordeaux

@placeybordeaux เพราะเช่นคุณอาจต้องการแปลงค่าและกำหนดให้กับตัวแปรอื่น ๆ โดยไม่คำนึงว่าคุณจะเปรียบเทียบกับสิ่งอื่นหรือไม่
DiegoDD

67

คำตอบมากมายที่ทำครึ่งหนึ่งของงาน ใช่!!Xสามารถอ่านได้ว่า "ความจริงของ X [แสดงเป็นบูลีน]" แต่!!ไม่ใช่การพูดจริงดังนั้นสำคัญสำหรับการหาว่าตัวแปรเดียวคือ (หรือแม้ว่าตัวแปรหลายตัว) ความจริงหรือเท็จ เป็นเช่นเดียวกับเพียง!!myVar === true myVarเมื่อเปรียบเทียบ!!Xกับบูลีน "ของจริง" ไม่มีประโยชน์จริงๆ

สิ่งที่คุณได้รับ!!คือความสามารถในการตรวจสอบความจริงของตัวแปรหลายตัวต่อกันในรูปแบบที่เป็นมาตรฐาน (และเป็นมิตรกับ JSLint) ที่ทำซ้ำได้

หล่อเพียง :(

นั่นคือ...

  • 0 === falsefalseเป็น
  • !!0 === falsetrueเป็น

ข้างต้นไม่ได้มีประโยชน์มาก if (!0)ให้ผลลัพธ์เหมือนกับif (!!0 === false)คุณ ฉันไม่สามารถนึกถึงกรณีที่ดีในการคัดเลือกตัวแปรเป็นบูลีนแล้วเปรียบเทียบกับบูลีน "ของจริง"

ดู "== และ! =" จากทิศทางของ JSLint (หมายเหตุ: Crockford กำลังเคลื่อนย้ายเว็บไซต์ของเขาไปรอบ ๆ ; ลิงก์นั้นมีแนวโน้มที่จะตายในบางจุด) เพราะเหตุผลเล็กน้อย:

ตัวดำเนินการ == และ! = จะพิมพ์ข้อความบังคับก่อนเปรียบเทียบ สิ่งนี้ไม่ดีเพราะทำให้ '\ t \ r \ n' == 0 เป็นจริง นี่สามารถปกปิดข้อผิดพลาดประเภท JSLint ไม่สามารถระบุได้อย่างน่าเชื่อถือว่า == มีการใช้อย่างถูกต้องหรือไม่ดังนั้นจึงเป็นการดีที่สุดที่จะไม่ใช้ == และ! = เลยและใช้ตัวดำเนินการ === และ! == ที่เชื่อถือได้มากกว่าเสมอ

หากคุณสนใจว่าคุณค่านั้นเป็นความจริงหรือเป็นเท็จให้ใช้แบบฟอร์มสั้น ๆ แทน
(foo != 0)

เพียงแค่พูดว่า
(foo)

และแทนที่จะ
(foo == 0)

พูด
(!foo)

โปรดทราบว่ามีบางกรณีที่ไม่ได้ใช้งานง่ายซึ่งบูลีนจะถูกส่งไปยังหมายเลข ( trueถูกส่งไปยัง1และfalseไปที่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 บางอย่างนั้นจะส่งออก -1 ในกล่องข้อความ! ลองใช้งานในพรอมต์ cmd.exe แล้วดู! แต่WScript.echo(-1 == test())ยังช่วยให้คุณมี 0 หรือ falseWScript เบือนหน้า. มันน่าเกลียด

เปรียบเทียบความจริง :)

แต่ถ้าฉันมีสองค่าฉันต้องตรวจสอบความจริงที่เท่าเทียมกัน / falsi-ness?

แกล้งเรามีและmyVar1 = 0;myVar2 = undefined;

  • myVar1 === myVar2เป็น0 === undefinedและเห็นได้ชัดว่าเป็นเท็จ
  • !!myVar1 === !!myVar2เป็น!!0 === !!undefinedและเป็นจริง! ความจริงเดียวกัน! (ในกรณีนี้ทั้งคู่ "มีความจริงเท็จ")

ดังนั้นที่เดียวที่คุณต้องใช้ "ตัวแปรแบบบูลีน" คือถ้าคุณมีสถานการณ์ที่คุณกำลังตรวจสอบว่าตัวแปรทั้งสองมีความเหมือนกันจริงไหม นั่นคือการใช้งาน!!ถ้าคุณจำเป็นต้องดูว่าสอง vars มีทั้ง truthy หรือทั้งสอง falsy (หรือไม่), ที่อยู่, เท่ากัน (หรือไม่) truthiness

ฉันไม่สามารถนึกถึงกรณีการใช้งานที่ยอดเยี่ยม บางทีคุณอาจมีฟิลด์ "ลิงก์" ในฟอร์มหรือไม่

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คอลเลกชันของคุณ


แก้ไข 24 ต.ค. 2560, 6 ก.พ. 19:

ไลบรารีของบุคคลที่สามที่ต้องการค่าบูลีนที่ชัดเจน

นี่เป็นกรณีที่น่าสนใจ ... !!อาจเป็นประโยชน์เมื่อ libs บุคคลที่สามคาดหวังค่าบูลีนที่ชัดเจน

ตัวอย่างเช่นFalse ใน JSX (ตอบสนอง) มีความหมายพิเศษที่ไม่ถูกเรียกใช้บนความเท็จง่าย หากคุณลองส่งคืนสิ่งต่อไปนี้ใน JSX ของคุณคาดว่าจะมี int ในmessageCount...

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

... คุณอาจประหลาดใจที่เห็น React ทำการแสดง0เมื่อคุณไม่มีข้อความ คุณต้องส่งคืนเท็จอย่างชัดเจนสำหรับ JSX ที่จะไม่แสดงผล ข้อความข้างต้นส่งคืน0ซึ่ง JSX แสดงผลอย่างมีความสุขเท่าที่ควร มันไม่สามารถบอกคุณไม่ได้มีCount: {messageCount && <div>Get your count to zero!</div>}(หรือสิ่งประดิษฐ์น้อยกว่า)

  • One fix เกี่ยวข้องกับ bangbang ซึ่งมีการรวม0เข้า!!0ด้วยfalseกันคือ:
    {!!messageCount && <div>You have messages!</div>}

  • JSX '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? หากmyObjectเป็นanyคุณจะกลับมาที่ Wild West ของ JavaScript และสามารถส่งคืนได้โดยไม่ต้องใช้!!แม้ว่าจะเป็นประเภทบูลีนก็ตาม

โปรดทราบว่าเหล่านี้เป็น JSX & typescript ประชุม , ไม่ได้คนโดยธรรมชาติเพื่อ JavaScript

แต่ถ้าคุณเห็นสิ่งแปลก ๆ0ใน JSX ที่แสดงผลของคุณให้คิดการจัดการที่ผิดพลาด


คำอธิบายที่ดี ดังนั้นคุณจะพูดว่า !! ไม่จำเป็นอย่างเคร่งครัดในตัวอย่างการตรวจจับคุณสมบัติผู้ปฏิบัติงานนี้หรือไม่ if (!!window.Worker)
jk7

2
ไม่คุณไม่ต้องการมัน ความจริงและtrue"ภายนอก" ทำงานเหมือนกันifทุกประการใน ฉันพยายามต่อไป แต่ฉันคิดไม่ออกว่ามีเหตุผลอะไรที่ชอบการชี้แนะความจริงกับค่าบูลีนนอกเหนือจากการจัดเรียงที่ซับซ้อน "เปรียบเทียบความจริง" กรณีด้านบนยกเว้นการอ่านหากคุณนำค่ามาใช้ใหม่ในภายหลังเช่นในqห้องสมุด . แต่ถึงอย่างนั้นมันก็เป็นทางลัดที่สูญเสียข้อมูลและฉันขอยืนยันว่าคุณดีกว่าที่จะประเมินความจริงทุกครั้ง
ruffin

React เป็นเหตุผลหลักที่เราเริ่มใช้ !! รูปแบบ แต่มันเป็นสิ่งที่สะดวกและทำซ้ำได้ ฉันแค่ต้องกังวลเกี่ยวกับความจริงหรือความผิดพลาดของบางสิ่งบางอย่างไม่ได้เป็นประเภทพื้นฐาน

Downvotes ที่ไม่มีความคิดเห็นทำให้ยากที่จะตอบข้อกังวลของคุณ แจ้งให้เราทราบสิ่งที่ดูไม่ดีและฉันยินดีที่จะกล่าว
ruffin

55

มันเป็นเพียงตัวดำเนินการ NOT แบบโลจิคัลสองครั้ง - มันใช้เพื่อแปลงบางสิ่งเป็นบูลีนเช่น:

true === !!10

false === !!0

3
คุณจะทำอย่างนั้นทำไมบนโลก? ใช้ ! โอเปอเรเตอร์เพื่อแปลงเป็นบูลีนแล้วใช้ === เพื่อเปรียบเทียบประเภท เพียงยอมรับว่าคุณไม่มีความปลอดภัยประเภทและทำ val> 0 หรืออะไรบางอย่าง
Darren Clark

43
@Darren: เขาไม่ได้เปรียบเทียบประเภท; เขาบอกคุณว่าผลลัพธ์คืออะไรโดยการเขียนคำยืนยันในคำตอบของเขา
การแข่งขัน Lightness ใน Orbit


26

มันเป็นการnotดำเนินการสองครั้ง ก่อน!จะแปลงค่าเป็นบูลีนและกลับค่าตรรกะ ครั้งที่สอง!กลับค่าตรรกะกลับ



23

มันจำลองพฤติกรรมของBoolean()ฟังก์ชั่นการคัดเลือกนักแสดง ครั้งแรกที่NOTส่งกลับค่าบูลีนไม่ว่าจะได้รับตัวถูกดำเนินการอะไร ครั้งที่สองNOTปฏิเสธBooleanค่านั้นและให้trueค่าบูลีนของตัวแปร ผลลัพธ์ที่ได้จะเหมือนกับการใช้Boolean()ฟังก์ชั่นกับค่า


20

! คือ "บูลีนไม่" ซึ่งโดยทั่วไปจะพิมพ์ค่า "เปิดใช้งาน" เป็นบูลีนที่ตรงกันข้าม ที่สอง ! พลิกค่านี้ ดังนั้น!!enableหมายถึง "ไม่เปิดใช้งาน" ซึ่งให้คุณค่าenableเป็นแบบบูล


18

ฉันคิดว่าน่าพูดถึงคือเงื่อนไขที่รวมกับตรรกะและ / หรือจะไม่คืนค่าบูลีน แต่ความสำเร็จครั้งสุดท้ายหรือความล้มเหลวครั้งแรกในกรณีของ && และความสำเร็จครั้งแรกหรือความล้มเหลวครั้งสุดท้ายในกรณีของ | | ของห่วงโซ่สภาพ

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ก็จะถูกแปลงเป็นตรรกะและได้รับการประเมินไปtrueเพราะเป็น 0 เพื่อให้คุณได้รับค่าที่ตรงกันข้ามและแปลงเป็นบูลีนจึงได้รับการประเมินเพื่อfalsytrue

!zero; //true

แต่เราไม่ต้องการให้ค่าบูลีนกลับด้านดังนั้นเราสามารถย้อนกลับได้อีกครั้งเพื่อให้ได้ผลลัพธ์ของเรา! !นั่นเป็นเหตุผลที่เราใช้อีก

โดยพื้นฐาน!!ทำให้เราแน่ใจว่ามูลค่าที่เราได้รับคือบูลีนไม่ผิดเพี้ยนความจริงหรือสตริง ฯลฯ ...

ดังนั้นจึงเหมือนกับการใช้Booleanฟังก์ชั่นใน javascript แต่วิธีที่ง่ายและสั้นกว่าในการแปลงค่าเป็นบูลีน:

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

15

!!สร้างเป็นวิธีที่ง่ายของการเปลี่ยนการแสดงออกใด ๆ ลงใน JavaScript เทียบเท่าบูลีนของมัน

ตัวอย่างเช่น: และ!!"he shot me down" === true!!0 === false


2
ใกล้เคียงกับความแตกต่างที่สำคัญ คีย์คือว่า0 === falseเป็นเท็จและ!!0 === falseเป็นจริง
ruffin

14

มันไม่ใช่โอเปอเรเตอร์เดียวมันคือสองตัว มันเทียบเท่ากับสิ่งต่อไปนี้และเป็นวิธีที่รวดเร็วในการแปลงค่าเป็นบูลีน

val.enabled = !(!enable);

10

ฉันสงสัยว่านี่เป็นส่วนที่เหลือจาก C ++ ที่ซึ่งผู้คนแทนที่! ตัวดำเนินการ แต่ไม่ใช่ตัวดำเนินการบูล

ดังนั้นเพื่อให้ได้คำตอบที่เป็นลบ (หรือบวก) ในกรณีนั้นคุณต้องใช้! ผู้ประกอบการที่จะได้รับบูลีน แต่ถ้าคุณต้องการที่จะตรวจสอบกรณีบวกจะใช้ !!


10

ifและwhileงบและ?ค่าใช้ประกอบการจริงเพื่อตรวจสอบว่าสาขาของรหัสที่จะวิ่ง ตัวอย่างเช่นตัวเลขศูนย์และ NaN และสตริงว่างเปล่าเป็นเท็จ แต่ตัวเลขและสตริงอื่น ๆ เป็นจริง วัตถุเป็นจริง แต่ค่าไม่ได้กำหนดและnullเป็นเท็จ

ตัวดำเนินการปฏิเสธคู่!!คำนวณค่าความจริงของค่า จริงๆแล้วมันเป็นผู้ให้บริการสองรายซึ่ง!!xหมายถึง!(!x)และมีพฤติกรรมดังต่อไปนี้:

  • ถ้าxเป็นค่าเท็จ!xเป็นtrueและเป็น!!xfalse
  • ถ้าxเป็นค่าจริง!xเป็นfalseและเป็น!!xtrue

เมื่อนำมาใช้ในระดับบนสุดของบริบทบูลีน ( if, whileหรือ?) ที่!!ประกอบเป็นพฤติกรรมไม่-op ตัวอย่างเช่น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)เป็นตรรกะและ 2 & 5คือ0(ค่าเท็จ); 2 && 5เป็นความจริง.

!!ผู้ประกอบการให้ความมั่นใจกับเครื่องมือผ้าสำลีว่าสิ่งที่คุณเขียนคือสิ่งที่คุณหมายถึงไม่ดำเนินการนี้จากนั้นนำค่าจริงของผล

การใช้งานครั้งที่สามคือการสร้างโลจิคัล XOR และโลจิคัล XNOR ในทั้ง C และ JavaScript ให้a && bดำเนินการตรรกะ AND (จริงถ้าทั้งสองฝ่ายเป็นจริง) และa & bดำเนินการ AND ระดับบิต a || bดำเนินการตรรกะหรือ (จริงถ้าอย่างน้อยหนึ่งเป็นจริง) และa | bดำเนินการระดับบิตหรือ มี bitor XOR (เป็นเอกสิทธิ์ OR) a ^ bแต่ไม่มีโอเปอเรเตอร์ในตัวสำหรับ XOR แบบลอจิคัล (จริงถ้าด้านใดด้านหนึ่งเป็นจริง) ตัวอย่างเช่นคุณอาจต้องการอนุญาตให้ผู้ใช้ป้อนข้อความในหนึ่งในสองฟิลด์ !!x !== !!yสิ่งที่คุณสามารถทำได้คือการแปลงแต่ละค่าความจริงและเปรียบเทียบพวกเขา


8

การปฏิเสธบูลีนซ้ำซ้อน มักใช้เพื่อตรวจสอบว่าค่าไม่ได้ไม่ได้กำหนด


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

คำถามนี้ได้รับการตอบค่อนข้างถี่ถ้วน แต่ฉันต้องการเพิ่มคำตอบที่ฉันหวังว่าจะทำให้เข้าใจง่ายที่สุดเท่าที่จะทำได้ทำให้ความหมายของ !! เป็นเรื่องง่ายที่จะเข้าใจเท่าที่จะทำได้

เพราะจาวาสคริปต์มีสิ่งที่เรียกว่า "truthy" และ "falsey" ค่ามีการแสดงออกว่าเมื่อประเมินในการแสดงออกอื่น ๆ ที่จะส่งผลให้อยู่ในสภาพที่เป็นจริงหรือเท็จแม้ว่าค่าหรือการแสดงออกจะถูกตรวจสอบไม่จริงหรือtruefalse

ตัวอย่างเช่น

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

หากองค์ประกอบนั้นมีอยู่จริงนิพจน์จะประเมินว่าเป็นจริงและบล็อกโค้ดจะถูกดำเนินการ

อย่างไรก็ตาม:

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

... จะไม่ส่งผลให้อยู่ในสภาพจริงและบล็อคโค้ดจะไม่ถูกดำเนินการแม้ว่าองค์ประกอบนั้นจะมีอยู่ก็ตาม

ทำไม? เพราะdocument.getElementById()เป็น "truthy" การแสดงออกที่จะประเมินว่าเป็นความจริงในเรื่องนี้if()คำสั่ง trueแต่มันไม่ได้เป็นค่าบูลีนที่แท้จริงของ

คู่ "ไม่" ในกรณีนี้ค่อนข้างง่าย มันเป็นเพียงสองnotกลับไปหลัง

คนแรกเพียง "กลับค่า" ความจริงหรือเท็จเป็นผลให้มีประเภทบูลีนที่แท้จริงและจากนั้นคนที่สอง "กลับ" มันกลับมาอีกครั้งเพื่อสถานะเดิม แต่ตอนนี้อยู่ในค่าบูลีนที่เกิดขึ้นจริง วิธีที่คุณมีความสอดคล้อง:

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

และ

if (!!document.getElementById('myElement') == 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

เคล็ดลับที่นี่คือ chain of &&s จะคืนค่าเท็จครั้งแรกที่พบ - และสามารถป้อนให้กับคำสั่ง if และอื่น ๆ ดังนั้นหาก b.foo ไม่ได้ถูกกำหนดไว้ก็จะส่งกลับ undefined และข้ามb.foo.barคำสั่งและเราไม่ได้รับ ความผิดพลาด

ผลตอบแทนดังกล่าวข้างต้นไม่ได้กำหนด แต่ถ้าคุณมีสตริงว่างเปล่า, เท็จ, โมฆะ, 0, ไม่ได้กำหนดค่าเหล่านั้นจะกลับมาและในไม่ช้าเมื่อเราพบพวกเขาในห่วงโซ่ - []และ{}เป็นทั้ง "ความจริง" และเราจะดำเนินการต่อไป && chain "เป็นค่าถัดไปทางขวา

PSอีกวิธีหนึ่งในการทำสิ่งเดียวกันคือ(b || {}).fooเพราะถ้า b ไม่ได้กำหนดb || {}จะเป็น{}และคุณจะเข้าถึงค่าในวัตถุว่างเปล่า (ไม่มีข้อผิดพลาด) แทนที่จะพยายามเข้าถึงค่าภายใน "undefined" (ทำให้เกิดข้อผิดพลาด ) ดังนั้น(b || {}).fooเป็นเช่นเดียวกับb && b.fooและเป็นเช่นเดียวกับ((b || {}).foo || {}).barb && 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;

ความตั้งใจของพวกเขาคือการตั้งค่า rafSupported เป็นจริงหรือเท็จขึ้นอยู่กับความพร้อมใช้งานของฟังก์ชั่นใน RequestAnimationFrame

สามารถทำได้โดยการตรวจสอบในวิธีต่อไปนี้โดยทั่วไป:

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

วิธีที่สั้นอาจใช้ !!

rafSupported = !!requestAnimationFrame ;

ดังนั้นหาก requestAnimationFrame ได้รับการกำหนดฟังก์ชั่นแล้ว! requestAnimationFrame จะเป็นเท็จและอีกหนึ่ง! ของมันจะเป็นจริง

ถ้า requestAnimationFrame ถูก assinged ไม่ได้กำหนดแล้ว! requestAnimationFrame จะเป็นจริงและอีกหนึ่ง! ของมันจะเป็นเท็จ


3

ตัวดำเนินการบางอย่างใน JavaScript ดำเนินการแปลงประเภทโดยนัยและบางครั้งใช้สำหรับการแปลงประเภท

ตัวดำเนิน!การunary แปลงตัวถูกดำเนินการของมันเป็นบูลีนและลบล้างมัน

ข้อเท็จจริงนี้นำไปสู่สำนวนต่อไปนี้ที่คุณเห็นในซอร์สโค้ดของคุณ:

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

3

ใช้ตัวดำเนินการเชิงตรรกะไม่ใช่ตัวคูณสองครั้ง
หมายความว่า! true = false
และ !! true = true


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ในการใช้งาน

โปรดตรวจสอบข้อมูลโค้ดด้านล่าง

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.