Tutorial (untuk Javascript) yang saya lakukan menyarankan agar kita menulis fungsi seperti ini:
function sayHello() {
//Some comments explaining the next line
window.alert("Hello");
}
Selain kebingungan, adakah manfaat menulis sesuatu seperti ini di kehidupan nyata? Jika demikian, apa manfaatnya?
language-agnostic
functions
Daniel
sumber
sumber
Jawaban:
Maafkan ingatan saya jika saya memiliki kesalahan ini ... Javascript bukan bahasa implementasi pilihan saya.
Ada beberapa alasan mengapa seseorang ingin memiliki fungsi tanpa arg membungkus panggilan fungsi lain. Sementara panggilan sederhana
window.alert("Hello");
adalah sesuatu yang bisa Anda bayangkan alih-alih menelepon langsung, bukansayHello()
.Tetapi bagaimana jika ada lebih dari itu? Anda punya selusin tempat di mana Anda ingin menelepon
sayHello()
danwindow.alert("Hello");
malah menulis . Sekarang Anda ingin melakukan awindow.alert("Hello, it is now " + new Date())
. Jika Anda membungkus semua panggilan itu saatsayHello()
Anda mengubahnya di satu tempat. Jika tidak, Anda mengubahnya di selusin tempat. Ini menyentuh pada Don't Repeat Yourself . Anda melakukannya karena Anda tidak ingin harus melakukannya selusin kali di masa depan.Saya bekerja dengan perpustakaan i18n / l10n di masa lalu yang menggunakan fungsi untuk melakukan lokalisasi sisi klien dari teks. Pertimbangkan
sayHello()
fungsinya. Anda bisa mencetaknyahola
saat pengguna dilokalkan ke bahasa Spanyol. Ini bisa terlihat seperti:Padahal, ini bukan cara perpustakaan bekerja. Sebagai gantinya, ia memiliki satu set file yang terlihat seperti:
Dan kemudian pustaka akan mendeteksi pengaturan bahasa browser dan kemudian membuat fungsi dinamis dengan lokalisasi yang sesuai sebagai nilai balik untuk pemanggilan fungsi tanpa arguemnt berdasarkan pada file lokalisasi yang sesuai.
Saya tidak cukup coder Javascript untuk mengatakan apakah itu baik atau buruk ... hanya itu dan dapat dilihat sebagai pendekatan yang mungkin.
Intinya, membungkus panggilan ke fungsi lain dalam suatu fungsinya sendiri seringkali cukup bermanfaat dan membantu dengan modularisasi aplikasi dan juga dapat menghasilkan kode yang lebih mudah dibaca.
Selain itu, Anda sedang mengerjakan tutorial. Penting untuk memperkenalkan hal-hal sesederhana mungkin di awal. Memperkenalkan panggilan fungsi gaya varargs dari awal dapat menghasilkan beberapa kode yang sangat membingungkan bagi seseorang yang tidak terbiasa dengan pengkodean secara umum. Jauh lebih mudah untuk beralih dari tanpa argumen, ke argumen, ke gaya varargs - dengan masing-masing membangun contoh dan pemahaman sebelumnya.
sumber
window.alert
juga sering digunakan sebagai pengganti selama pengembangan sampai modal / popup yang bagus dapat dirancang / diimplementasikan, jadi, sama seperti masalah bahasa, ia dapat diganti dengan lebih mudah. Atau jika Anda sudah memilikinya, pembaruan desain beberapa tahun ke depan mungkin memerlukan perubahan serupa.Saya pikir ini kadang berguna untuk menyembunyikan implementasi.
Dan ini memberi Anda fleksibilitas untuk mengubahnya nanti
sumber
sentralisasi: meskipun implementasinya panjang satu baris, jika itu garis yang sering berubah, Anda mungkin lebih suka mengubahnya di satu tempat, daripada di mana pun sayHello dipanggil.
meminimalkan / menyembunyikan dependensi: kode klien Anda tidak perlu lagi tahu ada objek jendela, dan Anda bahkan dapat mengubah seluruh implementasi tanpa mempengaruhi kode klien sama sekali
pemenuhan kontrak: kode klien dapat mengharapkan modul yang memiliki fungsi sayHello. Dalam hal ini, bahkan jika sepele, maka fungsi harus ada di sana.
konsistensi tingkat abstraksi: jika kode klien menggunakan operasi tingkat tinggi, Anda berkepentingan untuk menulis kode klien dalam istilah 'sayHello, sayBye' dan beberapa fungsi 'sayXXX' lainnya, alih-alih objek jendela. Infact, dalam kode klien Anda bahkan mungkin tidak ingin tahu ada yang namanya objek 'jendela'.
sumber
Luar biasa bahwa tidak ada satu orang pun yang menyebutkan pengujian.
Garis "terbungkus" tertentu yang Anda pilih,,
window.alert('hello')
sebenarnya adalah contoh sempurna dari ini. Apa pun yang melibatkanwindow
objek benar- benar menyakitkan untuk diuji. Lipat gandakan dengan 1000 kali dalam aplikasi Anda dan saya jamin para pengembang pada akhirnya akan menyerah pada pengujian. Di sisi lain, cukup mudah untuk hanya menghancurkansayHello
fungsi dengan mata-mata dan menguji apakah itu dipanggil.Contoh yang lebih praktis - karena sungguh, siapa yang sebenarnya menggunakan
window.alert(...)
kode produksi? - sedang memeriksa jam sistem. Jadi misalnya, ini akan menjadi pembungkusDateTime.Now
di .NET,time(...)
di C / C ++, atauSystem.currentTimeMillis()
di Jawa. Anda benar - benar ingin membungkus mereka dalam dependensi yang dapat Anda suntikkan, karena mereka tidak hanya (hampir) tidak mungkin untuk diejek / dipalsukan, mereka hanya baca dan non-deterministik . Setiap tes yang mencakup fungsi atau metode yang membuat penggunaan langsung dari fungsi jam sistem sangat mungkin menderita intermiten dan / atau kegagalan acak.Wrapper sebenarnya adalah fungsi 1-baris -
return DateTime.Now
- tetapi hanya itu yang Anda butuhkan untuk mengambil objek yang tidak dirancang dengan baik dan tidak dapat diuji dan menjadikannya objek yang bersih dan dapat diuji. Anda dapat mengganti jam palsu dengan pembungkus, dan mengatur waktunya untuk apa pun yang Anda inginkan. Masalah terpecahkan.sumber
Seperti yang Doval katakan, contoh ini mungkin hanya mencoba memperkenalkan Anda ke fungsi. Tapi saya umum, ini berguna. Terutama dengan menentukan beberapa tetapi tidak semua argumen, dan melewati yang lain, Anda dapat membuat fungsi yang lebih spesifik kasus dari fungsi yang lebih umum. Sebagai contoh yang agak sepele, pertimbangkan fungsi sortir yang membutuhkan array untuk disortir dan fungsi komparator untuk disortir. Dengan menentukan fungsi komparator yang membandingkan dengan nilai numerik, saya bisa membuat fungsi sortByNumericalValue, dan panggilan ke fungsi itu jauh lebih jelas dan ringkas.
sumber
Pemikiran di balik pertanyaan Anda tampaknya adalah: "Mengapa tidak
alert("Hello");
langsung menulis ? Ini cukup sederhana."Jawabannya adalah, sebagian, karena Anda tidak benar-benar ingin menelepon
alert("Hello")
- Anda hanya ingin menyapa.Atau: Mengapa menyimpan kontak di ponsel Anda, ketika Anda bisa memanggil nomor telepon saja? Karena Anda tidak ingin mengingat semua angka itu; karena memanggil nomor itu membosankan dan rentan kesalahan; karena jumlahnya mungkin berubah, tetapi masih orang yang sama di ujung lainnya. Karena Anda ingin memanggil orang , bukan angka.
Inilah yang dipahami oleh istilah-istilah seperti abstraksi, tipuan, "menyembunyikan detail implementasi", dan bahkan "kode ekspresif."
Alasan yang sama berlaku untuk menggunakan konstanta alih-alih menulis nilai mentah di mana-mana. Anda hanya bisa menulis
3.141592...
setiap kali Anda perlu π, tapi untungnya adaMath.PI
.Kita mungkin juga melihat
alert()
dirinya sendiri. Siapa yang peduli bagaimana ia membangun dan menampilkan dialog peringatan itu? Anda hanya ingin memberi tahu pengguna. Antara Anda menulisalert("Hello")
dan piksel pada layar Anda berubah, ada tumpukan kode dan perangkat keras yang dalam, dengan setiap lapisan memberi tahu apa yang diinginkannya berikutnya, dan lapisan berikutnya mengurus perincian sampai lapisan terdalam membalik beberapa bit di memori video.Anda benar-benar tidak ingin harus melakukan semua itu sendiri hanya untuk menyapa.
Pemrograman - yah, tugas apa pun, sungguh - adalah tentang memecah masalah yang rumit menjadi bagian yang dapat dikelola. Memecahkan setiap bagian memberi Anda blok bangunan, dan dengan blok bangunan yang cukup sederhana, Anda dapat membangun hal-hal besar.
Ini aljabar.
sumber
Merupakan ide bagus untuk menjaga agar perhitungan nilai (ekspresi) tidak terpisah dari eksekusi tindakan (pernyataan). Kami ingin kontrol yang tepat atas di mana dan kapan tindakan akan diambil (seperti menampilkan pesan), tetapi ketika menghitung nilai kami lebih suka bekerja pada tingkat yang lebih abstrak dan tidak perlu peduli tentang bagaimana nilai-nilai itu dihitung.
Fungsi yang hanya menghitung nilai balik, hanya menggunakan argumen yang diberikan, disebut murni .
"Fungsi" yang melakukan tindakan sebenarnya adalah prosedur , yang memiliki efek .
Setiap efek yang disebabkan selama perhitungan nilai disebut efek samping , dan lebih baik untuk menghindarinya jika memungkinkan ("Saya hanya membutuhkan string itu, saya tidak tahu itu akan memalu database!").
Untuk meminimalkan kemungkinan efek samping, kita harus menghindari pengiriman terlalu banyak data ke prosedur kita, atau memasukkan perhitungan apa pun ke dalamnya; jika beberapa perhitungan perlu dilakukan sebelumnya, biasanya lebih baik melakukannya secara terpisah dalam fungsi murni, kemudian hanya menyerahkan hasil yang diperlukan untuk prosedur. Ini menjaga tujuan prosedur tetap jelas, dan mengurangi kemungkinan bahwa itu akan digunakan kembali nanti sebagai bagian dari perhitungan (fungsi murni dapat digunakan kembali sebagai gantinya).
Untuk alasan yang sama, kita harus menghindari pemrosesan hasil di dalam suatu prosedur. Lebih baik mengembalikan hasil (jika ada) tindakan kami, dan melakukan pemrosesan selanjutnya dengan fungsi murni.
Jika kita mengikuti aturan ini, kita mungkin berakhir dengan prosedur seperti
sayHello
, yang tidak memerlukan data apa pun dan tidak memiliki hasil. Oleh karena itu antarmuka terbaik untuk itu adalah tidak memiliki argumen dan tidak mengembalikan nilai. Ini lebih disukai, misalnya, memanggil "console.log" di tengah-tengah beberapa perhitungan.Untuk mengurangi kebutuhan akan efek selama perhitungan, kita dapat memiliki perhitungan yang mengembalikan prosedur ; misalnya. jika kita perlu memutuskan tindakan yang akan diambil, kita dapat memiliki fungsi murni memilih prosedur dan mengembalikannya, daripada menjalankannya secara langsung.
Demikian juga, untuk mengurangi kebutuhan akan perhitungan selama prosedur, kita dapat meminta prosedur mengambil prosedur lain sebagai parameter (mungkin hasil dari suatu fungsi); misalnya. mengambil berbagai prosedur dan menjalankan satu demi satu.
sumber
setFoo
panggilan, karena itu menyiratkan data yang bisa berubah. Mengubah isi variabel / properti adalah efek, yang menyebabkan semua perhitungan menggunakan data tersebut menjadi tidak murni. Saya tidak akan merekomendasikanexecute
panggilan sendiri, tetapi saya akan merekomendasikanrunFoo
prosedur untuk melakukan tindakan berdasarkan argumen mereka.Saya akan mengatakan itu adalah kombinasi dari jawaban yang diberikan oleh @MichaelT dan @Sleiman Jneidi.
Mungkin ada sejumlah tempat dalam kode tempat Anda ingin menyapa pengguna dengan pesan Hello sehingga Anda mengemas ide itu dalam suatu metode. Dalam metode ini Anda dapat menerjemahkannya atau memperluas 'Halo' sederhana dengan menampilkan teks yang lebih panjang. Anda juga mungkin ingin menggunakan dialog JQuery yang bagus sebagai pengganti peringatan.
Intinya adalah implementasinya ada di satu tempat. Anda hanya perlu mengubah kode di satu tempat. (SayHello () mungkin adalah contoh yang terlalu sederhana)
sumber