Saya selalu diajari bahwa memiliki efek samping dalam suatu if
kondisi adalah buruk. Yang saya maksud;
if (conditionThenHandle()) {
// do effectively nothing
}
... sebagai lawan;
if (condition()) {
handle();
}
... dan saya mengerti itu, dan kolega saya senang karena saya tidak melakukannya, dan kami semua pulang pukul 17:00 pada hari Jumat dan semua orang memiliki akhir pekan yang meriah.
Sekarang, ECMAScript5 memperkenalkan metode seperti every()
dan some()
untuk Array
, dan saya menemukan mereka sangat berguna. Mereka lebih bersih daripada for (;;;)
, memberi Anda ruang lingkup lain, dan membuat elemen dapat diakses oleh variabel.
Namun ketika memvalidasi input, saya lebih sering menemukan diri saya menggunakan every
/ some
dalam kondisi untuk memvalidasi input, kemudian menggunakan every
/ some
lagi dalam tubuh untuk mengubah input menjadi model yang dapat digunakan;
if (input.every(function (that) {
return typeof that === "number";
})) {
input.every(function (that) {
// Model.findById(that); etc
}
} else {
return;
}
... ketika apa yang ingin saya lakukan adalah;
if (!input.every(function (that) {
var res = typeof that === "number";
if (res) {
// Model.findById(that); etc.
}
return res;
})) {
return;
}
... yang memberi saya efek samping dalam if
, kondisi, yang buruk.
Sebagai perbandingan, ini adalah kode yang akan terlihat dengan yang lama for (;;;)
;
for (var i=0;i<input.length;i++) {
var curr = input[i];
if (typeof curr === "number") {
return;
}
// Model.findById(curr); etc.
}
Pertanyaan saya adalah:
- Apakah ini benar-benar praktik yang buruk?
- Apakah saya (mis | ab) menggunakan
some
danevery
( haruskah saya menggunakanfor(;;;)
ini?) - Apakah ada pendekatan yang lebih baik?
sumber
some
, saya ingin melakukan sesuatu dengan elemen, jika saya menggunakanevery
, saya ingin melakukan sesuatu untuk semua elemen itu ...some
danevery
jangan biarkan saya mengakses informasi itu, jadi saya tidak bisa gunakan mereka, atau saya harus menambahkan efek samping.some
di sayaif
kondisi untuk menentukan apakah elemen tertentu dalam array pameran properti tertentu, 9/10 saya perlu untuk beroperasi pada elemen di sayaif
tubuh; sekarang, karenasome
tidak memberitahu saya yang dari unsur-unsur dipamerkan properti (hanya "satu melakukan"), saya bisa menggunakansome
lagi dalam tubuh (O (2n)), atau saya bisa saja melakukan operasi di dalam jika kondisi ( yang buruk, karena efek sampingnya di kepala).every
juga, tentu saja.Jawaban:
Jika saya memahami maksud Anda dengan benar, Anda tampaknya salah menggunakan atau menyalahgunakan
every
,some
tetapi itu sedikit tidak dapat dihindari jika Anda ingin mengubah elemen array Anda secara langsung. Koreksi saya jika saya salah, tetapi yang Anda coba lakukan adalah mencari tahu apakah beberapa atau setiap elemen dalam urutan Anda menunjukkan kondisi tertentu kemudian memodifikasi elemen-elemen itu. Juga, kode Anda tampaknya menerapkan sesuatu untuk semua item sampai Anda menemukan satu yang tidak lulus predikat dan saya tidak berpikir itu yang Anda maksudkan. Bagaimanapun.Mari kita ambil contoh pertama Anda (sedikit dimodifikasi)
Apa yang Anda lakukan di sini sebenarnya sedikit bertentangan dengan semangat beberapa / setiap / peta / kurangi / filter / konsep dll.
Every
tidak dimaksudkan untuk digunakan untuk memengaruhi setiap item yang sesuai dengan sesuatu, melainkan seharusnya hanya digunakan untuk memberi tahu Anda jika setiap item dalam koleksi melakukan hal yang sama. Jika Anda ingin menerapkan fungsi ke semua item yang predikatnya bernilai true, cara "baik" untuk melakukannya adalahAtau, Anda bisa menggunakan
foreach
alih-alih peta untuk memodifikasi item di tempat.Logika yang sama berlaku untuk
some
, pada dasarnya:every
untuk menguji apakah semua elemen dalam array lulus beberapa tes.some
untuk menguji apakah setidaknya satu elemen dalam array melewati beberapa tes.map
untuk mengembalikan array baru yang mengandung 1 elemen (yang merupakan hasil dari fungsi pilihan Anda) untuk setiap elemen dalam array input.filter
untuk mengembalikan array panjang 0 <length
<initial array length
elemen, semua yang terkandung dalam array asli dan semua lulus tes predikat disediakan.foreach
jika Anda ingin peta tetapi di tempatreduce
jika Anda ingin menggabungkan hasil array dalam hasil objek tunggal (yang bisa berupa array tetapi tidak harus).Semakin banyak Anda menggunakannya (dan semakin banyak Anda menulis kode LISP), semakin Anda menyadari bagaimana mereka terkait dan bagaimana bahkan mungkin untuk meniru / mengimplementasikan satu dengan yang lain. Yang kuat dengan pertanyaan ini dan yang benar-benar menarik adalah semantiknya, dan bagaimana mereka benar-benar mendorong Anda untuk menghilangkan efek samping berbahaya dalam kode Anda.
EDIT (berdasarkan komentar): Jadi katakanlah Anda ingin memvalidasi bahwa setiap elemen adalah objek dan mengubahnya menjadi Model Aplikasi jika semuanya valid. Salah satu cara untuk melakukan ini dalam sekali jalan adalah:
Dengan cara ini, ketika suatu objek tidak lulus validasi, Anda masih terus mengulangi seluruh array, yang akan lebih lambat daripada hanya memvalidasi dengan
every
. Namun, sebagian besar waktu array Anda akan valid (atau saya harap begitu), jadi dalam kebanyakan kasus Anda akan melakukan satu melewati array Anda dan berakhir dengan array yang dapat digunakan dari objek Model Aplikasi. Semantik akan dihormati, efek samping dihindari dan semua orang akan senang!Perhatikan bahwa Anda juga bisa menulis kueri Anda sendiri, mirip dengan foreach, yang akan menerapkan fungsi untuk semua anggota array dan mengembalikan true / false jika mereka semua lulus tes predikat. Sesuatu seperti:
Meskipun itu akan mengubah array di tempatnya.
Saya harap ini membantu, sangat menyenangkan untuk menulis. Bersulang!
sumber
if (input.every())
, untuk memeriksa bahwa setiap elemen adalah objek (typeof el === "object && el !== null
) dll, maka jika itu valid, saya ingin mengkonversi setiap elemen menjadi Model Aplikasi masing-masing (yang, sekarang Anda sebutkanmap()
saya bisa menggunakaninput.map(function (el) { return new Model(el); });
; tetapi tidak harus di tempat .map()
saya harus mengulangi array dua kali; satu kali untuk memvalidasi, dan satu lagi untuk dikonversi. Namun, dengan menggunakan standarfor(;;;)
lingkaran, aku bisa melakukan ini dengan menggunakan satu iterasi, tapi aku tidak bisa menemukan cara untuk menerapkanevery
,some
,map
ataufilter
dalam skenario ini, dan melakukan hanya satu lulus, tanpa tak diinginkan-efek samping atau sebaliknya memperkenalkan buruk- praktek.Efek samping tidak dalam kondisi if, mereka berada di dalam tubuh if. Anda hanya menentukan apakah akan mengeksekusi tubuh itu dalam kondisi aktual atau tidak. Tidak ada yang salah dengan pendekatan Anda di sini.
sumber
if
kondisi, dengan hanyareturn
berada di dalamif
tubuh; jelas saya sedang berbicara tentang contoh kode yang didahului oleh " apa yang ingin dilakukan adalah; ...if
kondisi.