Ada empat cara untuk menulis saklar JavaScript, tahukah Anda? Entah Anda menyadarinya atau tidak, saya tidak tahu.
Hanya ada satu cara untuk menulis pernyataan peralihan JavaScript yang saya tahu. Namun ketika menangani cabang, ada banyak cara untuk menulisnya. Metode penulisan cabang if dapat dihitung sebagai satu, metode penulisan cabang saklar dapat dihitung sebagai yang kedua, dan yang ketiga adalah menggunakan mode strategi. Jika operator kondisional juga disertakan, maka tepat ada empat.
tetapi protagonis artikel ini adalah switch. Semua orang tahu bahwa switch umumnya ditulis sebagai variabel atau ekspresi switch dan konstanta huruf besar/kecil. Misalnya, untuk skor seratus poin, 90 ke atas dianggap sangat baik, 80 ke atas dan di bawah 90 dianggap baik, 60 ke atas dan di bawah 80 dianggap memenuhi syarat, dan di bawah 60 dianggap tidak memenuhi syarat mungkin akan ditulis seperti ini:
function calcGrade(score ) { garis const = skor / 10 |. saklar (jalur) { kasus 10: kasus 9: kembalikan "Luar Biasa"; kasus 8: kembalikan "bagus"; kasus 7: kasus 6: kembalikan "memenuhi syarat"; bawaan: kembalikan "tidak memenuhi syarat"; } }
Pada kodenya, score / 10 | 0
mempunyai efek yang sama dengan Math.floor(score / 10)
, yaitu membagi dengan 10 untuk mendapatkan bagian bilangan bulat dari hasil bagi.
Switch ini digunakan dengan cukup baik, dan metode pembulatan untuk menghindari penggunaan daftar cabang if...else yang panjang juga merupakan trik yang cerdas.
Namun kini peraturan telah berubah dan titik pemisah antara yang memenuhi syarat dan yang baik telah diturunkan dari 80 poin menjadi 75 poin. Apa yang harus kami lakukan?
Cara pembulatan di atas masih bisa dilakukan, namun kali ini pembaginya bukan lagi 10, melainkan 5. Sejalan dengan itu, masih banyak lagi kasus:
18
jika... lain.
Apakah ini? Sebenarnya, ada cara yang lebih sederhana untuk menulis menggunakan switch:
function calcGrade(score) { beralih (benar) { skor kasus >= 90: kembalikan "Luar Biasa"; skor kasus >= 75: kembalikan "bagus"; skor kasus >= 60: kembalikan "memenuhi syarat"; bawaan: kembalikan "tidak memenuhi syarat"; } }
Apakah ini terasa sedikit aneh? Ini sama sekali bukan konstanta huruf besar-kecil ekspresi sakelar biasa, tetapi sebaliknya, ekspresi huruf besar-kecilan konstan pengganti! Jika Anda mengambil program ini dan menjalankannya, Anda akan menemukan bahwa tidak ada masalah sama sekali. Karena - switch dan case dicocokkan berdasarkan ===
, tidak peduli apakah itu ekspresi atau konstanta, atau dengan kata lain, switch dan case dapat diikuti dengan ekspresi!
Ya, ekspresi!
Jadi pada contoh di atas, mengubah switch(true)
switch( 2 > 1)
memiliki efek yang sama.
Oke, pikiranku terbuka. Tidak peduli berapa banyak cara Anda dapat menulis saklar. Hal berikutnya yang perlu dicermati adalah varian switch.
: Saya melihat C# memiliki ekspresi switch, dan saya iri. Bisakah itu diimplementasikan?
Jangan khawatir, semua yang ada di JavaScript bisa berupa ekspresi... Jika tidak, gunakan saja IIFE untuk merangkum satu
fungsi calcGrade(score) { kembali (nilai => { beralih (benar) { nilai kasus >= 90: kembalikan "Luar Biasa"; nilai kasus >= 75: kembalikan "bagus"; nilai kasus >= 60: kembalikan "memenuhi syarat"; bawaan: kembalikan "tidak memenuhi syarat"; } })(skor); }
Perhatikan bahwa score
digunakan sebagai parameter IIFE di sini karena dalam penggunaan sebenarnya, sebuah ekspresi mungkin perlu diteruskan. Dalam hal ini sebaiknya dievaluasi terlebih dahulu dan hanya sekali saja (untuk menghindari efek samping substitusi).
Namun enkapsulasi seperti itu jelas tidak ada artinya. Jika Anda benar-benar ingin merangkumnya seperti ini, lebih baik merangkumnya sebagai strategi:
function calcGrade(score) { return ((nilai, aturan) => aturan.find(({ t }) => t(nilai)).v)( skor, [ { t: n => n >= 90, v: "Luar Biasa" }, { t: n => n >= 75, v: "Bagus" }, { t: n => n >= 60, v: "Memenuhi syarat" }, { t: () => benar, v: "tidak memenuhi syarat" }, ] ); }
Setiap strategi adalah objek yang berisi tester ( t
) dan nilai ( v
). tester adalah fungsi penilaian yang meneruskan nilai yang perlu dinilai, yang merupakan ekspresi di sini dalam switch (表达式)
, dan ekspresi ini juga diteruskan sebagai parameter IIFE setelah dievaluasi terlebih dahulu. Proses penerapan suatu strategi sederhana dan kasar, yaitu menemukan strategi pertama yang memenuhi syarat dan mengambil nilainya.
Tentu saja strategi ini agak berlebihan. Ketika Anda benar-benar perlu menggunakan suatu strategi, strategi tersebut biasanya bukanlah suatu nilai, melainkan suatu perilaku, yaitu suatu fungsi.
Kita tahu bahwa dalam pernyataan switch, setiap case berada dalam lingkup yang sama, sehingga variabel lokal yang sama tidak dapat dideklarasikan dalam dua pernyataan case. Meskipun membungkus dengan { }
dapat mengatasi masalah ini, kodenya tidak terlihat bagus, terutama hati-hati jangan sampai lupa break
. Jika Anda menggunakan sebuah strategi, mungkin terlihat enak dipandang, dan Anda tidak perlu khawatir dengan masalah break:
di sini untuk tujuan demonstrasi, dalam perilaku strategi, hasilnya akan dikeluarkan terlebih dahulu, baru kemudian levelnya akan ditampilkan. kembali.
fungsi calcGrade(skor) { return ((nilai, aturan) => aturan.find(({ t }) => t(nilai)).fn(nilai))( skor, [ { t: n => n >= 90, fn: skor => { const grade = "Luar Biasa"; console.log(nilai, skor); nilai kembali; } }, { t: n => n >= 75, fn: skor => { nilai const = "baik"; console.log(nilai, skor); nilai kembali; } }, { t: n => n >= 60, fn: skor => { nilai const = "lulus"; console.log(nilai, skor); nilai kembali; } }, { t: () => benar, fn: skor => { const grade = "tidak memenuhi syarat"; console.log(nilai, skor); nilai kembali; } }, ] ); }
Kodenya memang agak panjang karena terdapat logika perilaku strategis di dalamnya. Kalau memang mau dijadikan switch ekspresi , bagian strateginya harus berupa ekspresi, jangan terlalu panjang. Pada kode di atas, perilaku strategi serupa dan dapat dienkapsulasi menjadi sebuah fungsi, sehingga dapat ditulis dalam bentuk ekspresi:
function calcGrade(score) { const printGrade = (nilai, skor) => { console.log(nilai, skor); nilai kembali; }; return ((nilai, aturan) => aturan.find(({ t }) => t(nilai)).fn(nilai))( skor, [ { t: n => n >= 90, fn: skor => printGrade("Luar Biasa", skor) }, { t: n => n >= 75, fn: skor => printGrade("Bagus", skor) }, { t: n => n >= 60, fn: skor => printGrade("memenuhi syarat", skor) }, { t: () => benar, fn: skor => printGrade("tidak memenuhi syarat", skor) }, ] ); }
Apakah sekarang terlihat rapi?
Kode-kode di atas mempunyai bentuk yang berbeda-beda dan fungsinya serupa, dan tidak ada perbandingan mana yang lebih baik. Apa pun yang Anda sukai, Anda anggun; apa pun yang tidak Anda sukai, Anda tidak disukai. Dalam situasi yang berbeda, pilih saja pendekatan yang sesuai. Kode di atas menggunakan find()
untuk menemukan strateginya. Jika filter()
digunakan, ceritanya akan berbeda.