ทับทิม || = (หรือเท่ากับ) ใน JavaScript?


128

ฉันรัก||=กลไกของรูบี้ หากไม่มีหรือมีตัวแปรnilให้สร้างและตั้งค่าให้เท่ากับบางสิ่ง:

amount # is nil
amount ||= 0 # is 0
amount ||= 5 # is 0

ตอนนี้ฉันต้องทำสิ่งที่คล้ายกันใน JavaScript อะไรคือแบบแผนหรือวิธีที่เหมาะสมในการทำเช่นนี้? ฉันรู้ว่า||=ไม่ใช่ไวยากรณ์ที่ถูกต้อง 2 วิธีที่ชัดเจนในการจัดการคือ:

window.myLib = window.myLib || {};

// or

if (!window.myLib)
  window.myLib = {};

คำตอบ:


152

ทั้งสองอย่างนั้นถูกต้อง แต่ถ้าคุณกำลังมองหาสิ่งที่เหมือน||=ในทับทิม วิธีแรกซึ่งเป็นวิธีที่variable = variable || {}คุณกำลังมองหา :)


1
ระมัดระวังในการใช้สิ่งนี้หากค่าที่ถูกต้องสำหรับxเป็นเท็จเช่นfalseและคุณต้องการตั้งค่าเริ่มต้นเมื่อxไม่ได้กำหนดเท่านั้น
Joshua Pinter

ความคิดเห็นด้านบนถูกต้อง จากกรณีตัวอย่างของคุณมันจะไม่ทำงานในลักษณะเดียวกันใน JS let amount = 0;ตามด้วยamount = amount || 5 จำนวนเงินที่เปลี่ยนแปลงจะไป 5. หากคุณไม่ต้องการที่จะเกิดขึ้นใช้ประกอบการแทน?? ||
AshwinKumarS

@AshwinKumarS หรือแค่ใช้amount ??= 5;.
user4642212

@ user4642212 ฉันไม่คิดว่าไวยากรณ์ทำงานใน JS ใช่หรือไม่
AshwinKumarS

@AshwinKumarS ใช่ค่ะ ดูเอกสาร , สเปค , ข้อเสนอ
user4642212

22

คุณสามารถใช้ตัวดำเนินการตรรกะ OR ||ซึ่งประเมินตัวถูกดำเนินการที่ถูกต้องหากlValเป็นค่าที่ไม่ถูกต้อง

ค่าเท็จ ได้แก่ null, false, 0, "", undefined, NaN

x = x || 1

ระมัดระวังในการใช้สิ่งนี้หากค่าที่ถูกต้องสำหรับxเป็นเท็จเช่นfalseและคุณต้องการตั้งค่าเริ่มต้นเมื่อxไม่ได้กำหนดเท่านั้น
Joshua Pinter

4

หากคุณกำลังทำงานกับวัตถุคุณสามารถใช้การทำลายโครงสร้าง (ตั้งแต่ ES6) ดังนี้:

({ myLib: window.myLib = {} } = window);

... แต่คุณไม่ได้อะไรจากคำตอบที่ยอมรับนอกจากความสับสน


1
"แต่คุณไม่ได้อะไรจากคำตอบที่ยอมรับนอกจากความสับสน" - ดี :)
lindes

ฉันพนันได้เลยว่าใครบางคนจะใช้สิ่งนี้เป็นเหตุผลที่จะเกลียดจาวาสคริปต์
Volper

1

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

คุณสามารถใช้มันตอนนี้ใช้ปลั๊กอิน-ข้อเสนอตรรกะมอบหมายประกอบปลั๊กอินบาเบล ฉันไม่เคยใช้ปลั๊กอินนั้นดังนั้นฉันจึงไม่รู้ว่ามันทำงานได้ดีแค่ไหน


-1

ทับทิม || = การกำหนดวงจรสั้นของตัวดำเนินการ คิดได้ดังนี้

return a || a = b

ดังนั้นในจาวาสคริปต์สิ่งนี้จึงดูคล้ายกันมาก:

return a || (a = b);

ดูเหมือนตามที่ระบุไว้ในความคิดเห็นด้านล่างอย่างไรก็ตามรูปแบบทับทิมตามตัวอักษรนี้มีประสิทธิภาพน้อยกว่าสำนวนจาวาสคริปต์มาตรฐาน a = a || ข

สำหรับการอ้างอิง: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html


1
ในทางปฏิบัติดูเหมือนว่าa = a || bแบบฟอร์มจะเหมาะสมกว่า jsperf.com/x-or-x-equals-0-vs-x-equals-x-or-0/3
jchook

อาเครื่องมือที่ยอดเยี่ยม จะเป็นอย่างไรถ้า x มีค่าและลัดวงจร?
chris

ฉันเชื่อว่าการฉีกขาดจำเป็นต้องมีความชัดเจนใน jsperf ดังนั้นการทดสอบนี้ควรแสดงประสิทธิภาพการลัดวงจร ฉันเดาว่า V8 a = a || bมีการเพิ่มประสิทธิภาพพิเศษสำหรับแบบฟอร์ม
jchook

3
FYI ดูเหมือนว่าความแตกต่างใด ๆ ที่มีอยู่ตอนนี้ได้รับการปรับให้เหมาะสมแล้ว
Charles Wood

a || (a = b)มีความหมายที่ถูกต้องในการอนุมานชื่อฟังก์ชัน ขณะนี้อยู่ระหว่างการหารือเกี่ยวกับข้อเสนอใหม่
user4642212

-1

คุณสามารถบรรลุพฤติกรรมที่ต้องการโดยใช้ตัวดำเนินการ | = ในจาวาสคริปต์สำหรับจำนวนเต็มเท่านั้น แต่คุณต้องกำหนดตัวแปรก่อน

let a = 0
a |= 100
console.log(a) // 100

สำหรับวัตถุ

let o = {}
o.a |= 100
console.log(o) // {a: 100}

สำหรับอาร์เรย์

let arr = []
arr[0] |= 100
console.log(arr) // [100]

คำถามคือไม่ได้เกี่ยวกับหรือ| |=พฤติกรรมที่ต้องการในคำถามนั้นไม่เกี่ยวข้องกับการดำเนินการแบบบิต
user4642212

คุณพูดถูกฉันจะแก้ไขคำตอบตามนั้น
wallgeek

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