มีสี่วิธีในการเขียนสวิตช์ JavaScript คุณรู้หรือไม่? คุณรู้หรือไม่ฉันไม่รู้
มีเพียงวิธีเดียวเท่านั้นที่จะเขียนคำสั่งสวิตช์ JavaScript ที่ฉันรู้จัก แต่เมื่อพูดถึงการจัดการกิ่งไม้ มีหลายวิธีในการเขียน ถ้าวิธีเขียนสาขาสามารถนับได้เป็นหนึ่ง วิธีเขียนสาขาของสวิตช์สามารถนับเป็นวิธีที่สองได้ และวิธีที่สามคือการใช้โหมดกลยุทธ์ หากรวมตัวดำเนินการแบบมีเงื่อนไขด้วย ก็จะมีสี่วิธีอย่างแน่นอน
แต่ตัวเอกของบทความนี้คือ switch ทุกคนรู้ดีว่าโดยทั่วไปสวิตช์จะเขียนเป็นตัวแปรหรือนิพจน์ของสวิตช์และค่าคงที่ตัวพิมพ์ ตัวอย่างเช่น สำหรับคะแนนร้อยคะแนน 90 ขึ้นไปถือว่าดีเยี่ยม 80 ขึ้นไปและต่ำกว่า 90 ถือว่าดี 60 ขึ้นไปและต่ำกว่า 80 ถือว่าผ่านเกณฑ์ และต่ำกว่า 60 ถือว่าไม่มีคุณสมบัติ อาจจะเขียนแบบนี้:
function calcGrade(score ) { เส้น const = คะแนน / 10 | 0; สวิตช์ (บรรทัด) { กรณีที่ 10: กรณีที่ 9: ส่งคืน "ยอดเยี่ยม"; กรณีที่ 8: กลับ "ดี"; กรณีที่ 7: กรณีที่ 6: ส่งคืน "ผ่านการรับรอง"; ค่าเริ่มต้น: ส่งคืน "ไม่มีเงื่อนไข"; - }
ในโค้ด score / 10 | 0
มีผลเช่นเดียวกับ Math.floor(score / 10)
ซึ่งก็คือหารด้วย 10 เพื่อให้ได้ส่วนจำนวนเต็มของผลหาร
สวิตช์นี้ใช้งานได้ค่อนข้างดี และวิธีการปัดเศษเพื่อหลีกเลี่ยงการใช้รายการ if...else จำนวนมากก็เป็นกลอุบายที่ชาญฉลาดเช่นกัน
แต่ตอนนี้กฎเปลี่ยนไปและจุดแยกระหว่างคุณสมบัติและความดีลดลงจาก 80 คะแนนเหลือ 75 คะแนน เราควรทำอย่างไร?
วิธีการปัดเศษข้างต้นยังคงเป็นไปได้ แต่คราวนี้ตัวหารไม่ใช่ 10 อีกต่อไป แต่เป็น 5 ตามลำดับ มีอีกหลายกรณี:
เขียน 9 กรณี ควรใช้ ถ้า... อย่างอื่น
มันไม่? อันที่จริง มีวิธีที่ง่ายกว่าในการเขียนโดยใช้สวิตช์:
function calcGrade(score) { สวิตช์ (จริง) { คะแนนกรณี >= 90: ส่งคืน "ยอดเยี่ยม"; คะแนนเคส >= 75: กลับ "ดี"; คะแนนกรณี >= 60: ส่งคืน "ผ่านการรับรอง"; ค่าเริ่มต้น: ส่งคืน "ไม่มีเงื่อนไข"; - }
รู้สึกแปลกๆ นิดหน่อยหรือเปล่า? นี่ไม่ใช่ค่าคงที่ตัวพิมพ์ของนิพจน์สวิตช์ปกติเลย แต่ตรงกันข้ามคือเปลี่ยนนิพจน์ตัวพิมพ์คงที่! หากคุณนำโปรแกรมนี้มาใช้งานคุณจะพบว่าไม่มีปัญหาใดๆ เลย เนื่องจาก - switch และ case ตรงกันตาม ===
ไม่สนใจว่าจะเป็นนิพจน์หรือค่าคงที่ หรือกล่าวอีกนัยหนึ่ง switch และ case สามารถตามด้วยนิพจน์ได้!
ใช่แล้ว การแสดงออก!
จากตัวอย่างข้างต้น การเปลี่ยน switch(true)
switch( 2 > 1)
จะให้ผลเช่นเดียวกัน
โอเค ใจฉันเปิดแล้ว ไม่สำคัญว่าคุณจะเขียนสวิตช์ได้กี่วิธี สิ่งต่อไปที่ต้องดูคือตัวแปรสวิตช์
: ฉันเห็นว่า C# มีสำนวนสวิตช์ และฉันก็อิจฉา มันสามารถนำไปใช้ได้หรือไม่?
ไม่ต้องกังวล ทุกอย่างใน JavaScript อาจเป็นนิพจน์ได้... ถ้าไม่เช่นนั้น ให้ใช้ IIFE เพื่อรวม
ฟังก์ชัน calcGrade(score) { กลับ (ค่า => { สวิตช์ (จริง) { ค่าตัวพิมพ์ >= 90: ส่งคืน "ยอดเยี่ยม"; ค่าตัวพิมพ์ >= 75: กลับ "ดี"; ค่าตัวพิมพ์ >= 60: ส่งคืน "ผ่านการรับรอง"; ค่าเริ่มต้น: ส่งคืน "ไม่มีเงื่อนไข"; - })(คะแนน); }
โปรดทราบว่า score
ถูกใช้เป็นพารามิเตอร์ของ IIFE ที่นี่ เนื่องจากในการใช้งานจริง อาจจำเป็นต้องส่งนิพจน์เข้าไป ในกรณีนี้ ควรได้รับการประเมินล่วงหน้าเพียงครั้งเดียวเท่านั้น (เพื่อหลีกเลี่ยงผลข้างเคียงจากการเปลี่ยนตัว)
อย่างไรก็ตาม การห่อหุ้มดังกล่าวไม่มีความหมายอย่างเห็นได้ชัด หากคุณต้องการห่อหุ้มแบบนี้จริงๆ จะเป็นการดีกว่าถ้าห่อหุ้มไว้เป็นกลยุทธ์:
function calcGrade(score) { return ((ค่า, กฎ) => Rules.find(({ t }) => t(ค่า)).v)( คะแนน, - { t: n => n >= 90, v: "ยอดเยี่ยม" }, { t: n => n >= 75, v: "ดี" } { t: n => n >= 60, v: "ผ่านการรับรอง" }, { t: () => จริง, v: "ไม่มีเงื่อนไข" }, - - }
แต่ละกลยุทธ์คือออบเจ็กต์ที่มีผู้ทดสอบ ( t
) และค่า ( v
) ผู้ทดสอบคือฟังก์ชันการตัดสินที่ส่งผ่านค่าที่ต้องพิจารณา ซึ่งเป็นนิพจน์ใน switch (表达式)
และนิพจน์นี้ยังถูกส่งผ่านเป็นพารามิเตอร์ของ IIFE หลังจากที่ได้รับการประเมินล่วงหน้าแล้ว กระบวนการใช้กลยุทธ์นั้นง่ายและไม่ซับซ้อน ซึ่งก็คือการค้นหากลยุทธ์แรกที่ตรงตามเงื่อนไขและดึงมูลค่าของมันออกมา
แน่นอนว่ากลยุทธ์นี้ค่อนข้างเกินกำลังไปหน่อย เมื่อคุณต้องการใช้กลยุทธ์จริงๆ กลยุทธ์มักจะไม่ใช่คุณค่า แต่เป็นพฤติกรรม ซึ่งก็คือฟังก์ชัน
เรารู้ว่าในคำสั่ง switch แต่ละกรณีจะอยู่ในขอบเขตเดียวกัน ดังนั้นจึงไม่สามารถประกาศตัวแปรท้องถิ่นเดียวกันในคำสั่งสองกรณีได้ แม้ว่าการห่อด้วย { }
จะสามารถแก้ปัญหาเหล่านี้ได้ แต่โค้ดก็ดูไม่ดีนัก โดยเฉพาะอย่างยิ่งระวังอย่าลืม break
หากคุณใช้กลยุทธ์ มันอาจดูน่าพึงพอใจ และคุณไม่ต้องกังวลเกี่ยวกับปัญหาการแตกหัก:
ที่นี่เพื่อการสาธิต ในลักษณะการทำงานของกลยุทธ์ ผลลัพธ์จะถูกส่งออกก่อน จากนั้นระดับจะเป็น กลับมา
ฟังก์ชั่น calcGrade (คะแนน) { return ((ค่า, กฎ) => Rules.find(({ t }) => t(ค่า)).fn(ค่า))( คะแนน, - - เสื้อ: n => n >= 90, Fn: คะแนน => { เกรด const = "ดีเยี่ยม"; console.log(เกรด, คะแนน); ส่งคืนเกรด; - - - เสื้อ: n => n >= 75, Fn: คะแนน => { เกรด const = "ดี"; console.log(เกรด, คะแนน); ส่งคืนเกรด; - - - เสื้อ: n => n >= 60, Fn: คะแนน => { const grade = "ผ่าน"; console.log(เกรด, คะแนน); ส่งคืนเกรด; - - - เสื้อ: () => จริง, Fn: คะแนน => { const grade = "ไม่มีเงื่อนไข"; console.log(เกรด, คะแนน); ส่งคืนเกรด; - - - - }
โค้ดอาจยาวสักหน่อยเนื่องจากมีตรรกะพฤติกรรมเชิงกลยุทธ์อยู่ในนั้น หากจะใช้เป็น นิพจน์ สวิตช์จริงๆ ส่วนกลยุทธ์ควรเป็นนิพจน์ไม่ยาวเกินไป ในโค้ดข้างต้น ลักษณะการทำงานของกลยุทธ์จะคล้ายกันและสามารถสรุปเป็นฟังก์ชันได้ เพื่อให้สามารถเขียนในรูปแบบของนิพจน์:
function calcGrade(score) { const printGrade = (เกรด, คะแนน) => { console.log(เกรด, คะแนน); ส่งคืนเกรด; - return ((ค่า, กฎ) => Rules.find(({ t }) => t(ค่า)).fn(ค่า))( คะแนน, - { t: n => n >= 90, fn: คะแนน => printGrade("ยอดเยี่ยม", คะแนน) }, { t: n => n >= 75, fn: คะแนน => printGrade("ดี", คะแนน) }, { t: n => n >= 60, fn: คะแนน => printGrade("เข้าเกณฑ์", คะแนน) }, { t: () => true, fn: คะแนน => printGrade("ไม่มีคุณสมบัติ", คะแนน) }, - - }
ตอนนี้มันดูเรียบร้อยหรือยัง?
โค้ดด้านบนมีรูปแบบที่แตกต่างกันและทำสิ่งที่คล้ายกัน และไม่มีการเปรียบเทียบว่าอันไหนดีกว่ากัน ไม่ว่าคุณจะชอบอะไร คุณก็สง่างาม ไม่ว่าคุณจะไม่ชอบอะไร ก็ไม่เป็นที่โปรดปราน ในสถานการณ์ต่างๆ เพียงแค่เลือกแนวทางที่เหมาะสม โค้ดด้านบนใช้ find()
เพื่อค้นหากลยุทธ์ หากใช้ filter()
แทน ก็จะเป็นอีกเรื่องหนึ่ง