ตัวดำเนินการ Ternary ของ Javascript เทียบกับ ||


17

ฉันดูโค้ด node.js ก่อนหน้านี้และฉันสังเกตเห็นว่าคนที่เขียนมันดูเหมือนจะชอบไวยากรณ์ต่อไปนี้:

var fn = function (param) {
    var paramWithDefault = null == param ? 'Default Value' : param;
}

ในสิ่งที่ฉันคิดว่ากระชับกว่า:

var fn = function (param) {
    var paramWithDefault = param || 'Default Value';
}

ฉันสงสัยว่ารูปแบบที่สองเป็นไวยากรณ์ JavaScript ที่สังคมยอมรับได้มากกว่าหรือไม่ฉันเคยเห็นรูปแบบที่แปลกประหลาดมากกว่าตัวดำเนินการแบบไตรภาคเพื่อจุดประสงค์นี้หรือไม่

ฉันสังเกตว่าในตัวอย่างแรกเขาใช้สองเท่า (ไม่ใช่สามเท่า) ซึ่งหมายความว่ามันจะนับว่า "ไม่ได้กำหนด" เป็นโมฆะซึ่งจะลดผลกระทบที่ฉันคิดได้ อย่างไรก็ตามฉันได้อ่านในหลาย ๆ ที่ == เป็นตัวดำเนินการที่ค่อนข้างชั่วร้ายใน JavaScript (JSLint เป็นอย่างมากต่อ IIRC)


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

คำตอบ:


17

เนื่องจากรหัสนี้จะประเมินเป็น 'ค่าเริ่มต้น' ทุกครั้งที่คุณผ่านเป็น 0, "", เท็จหรือค่าเท็จอื่น ๆ

function fn(param) {
  var paramWithDefault = param || 'Default Value';
  return paramWithDefault;
}

มันอาจไม่กัดคุณในการใช้ฟังก์ชั่นนี้ แต่มันเป็นรูปแบบที่ไม่ดีที่จะหลีกเลี่ยงเมื่อคุณสนใจที่จะส่งผ่านสิ่งต่าง ๆ เช่นสตริงว่างหรือ 0 หรือบูลีน


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

4
การเปรียบเทียบศูนย์เป็นจุดที่ดีซึ่งอาจไม่คาดคิดเลยทีเดียว
Ed James

1
+1 - ปัญหานี้เป็นสาเหตุที่ทำให้ Python (ในที่สุด) เพิ่มไวยากรณ์ "x if y else z" ซีแมนทิกส์เหล่านั้นสำหรับตัวดำเนินการเชิงตรรกะนั้นค่อนข้างพบได้ทั่วไปและข้อผิดพลาดทั่วไปที่เหมือนกันนั้นมีแนวโน้มที่จะครอบตัดเมื่อใดก็ตามที่สำนวนต้องพึ่งพาพวกมันเพื่อทำงานของตัวดำเนินการคัดเลือกตามเงื่อนไข
Steve314

ก็ไม่ลืมที่จะนำโครงสร้างของคุณในวงเล็บถ้าคุณใช้พวกเขาร่วมกันกับสตริงvar txt = 'Hello, ' + (user_name||'User') + '!';จะทำงาน แต่ไม่มี parenthesizes - undefinedคุณจะได้รับ jsfiddle.net/4mFAB/1
c69

7

สิ่งที่คุณต้องการจริงๆคือโอเปอเรเตอร์รวมกันเป็นโมฆะ แต่เมื่อเห็นว่าจาวาสคริปต์นั้นไม่มีอยู่จริงๆแล้วโปรแกรมเมอร์มักจะใช้ '||' ที่จะยืนในมัน

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


ตัวดำเนินการอื่นที่เกี่ยวข้องคือตัวดำเนินการไอคอนสะกด IIRC "else" สิ่งนี้จะรับรู้ผลลัพธ์ "ล้มเหลว" พิเศษจากอาร์กิวเมนต์แรกและใช้อาร์กิวเมนต์ที่สองในกรณีนั้นเป็นทางเลือก ฉันต้องการให้ Pythons "x ถ้า y else z" ถูกใช้งานโดยใช้ตัวดำเนินการสองตัวแยกกัน - ตัวดำเนินการ "if" กับตัวดำเนินการยืนยันแบบไบนารีและตัวดำเนินการแบบไอคอน "แบบอื่น" - โดยที่ตัวดำเนินการทั้งสองนั้นสามารถใช้งานได้อย่างอิสระ อย่างไรก็ตามไอคอนไม่รองรับสไตล์นั้นแทนที่จะทำอะไรที่แปลกประหลาดกับตัวดำเนินการสัมพัทธ์
Steve314

@ Steve314: Python มีบางสิ่งที่คุณต้องการ: ตัวดำเนิน[false-part, true-part]การแยกต่างหากที่มีตัวแยกต่างหากหากตัวดำเนินการ[..][bool(condition)]รวมเข้า[false-part, true-part][bool(condition)]ด้วยกัน หากคุณต้องการพฤติกรรมขี้เกียจคุณสามารถแลมบ์ดาส่วนที่แท้จริงและเท็จได้
โกหก Ryan

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