Ekspresi lambda C # juga memiliki penutup tetapi jarang dibahas oleh komunitas atau buku C #. Saya melihat jauh lebih banyak orang JavaScript dan buku berbicara tentang penutupannya daripada di dunia C #. Mengapa demikian?
Ekspresi lambda C # juga memiliki penutup tetapi jarang dibahas oleh komunitas atau buku C #. Saya melihat jauh lebih banyak orang JavaScript dan buku berbicara tentang penutupannya daripada di dunia C #. Mengapa demikian?
Jawaban:
Karena javascript tidak memiliki fitur seperti namespace, dan Anda dapat mengacaukan dengan mudah dengan semua jenis objek global.
Jadi, penting untuk dapat mengisolasi beberapa kode di lingkungan eksekusi sendiri. Penutupan sempurna untuk itu.
Penggunaan penutupan ini tidak masuk akal dalam bahasa seperti C # di mana Anda memiliki ruang nama, kelas, dan sebagainya untuk mengisolasi kode dan tidak menempatkan semuanya dalam lingkup global.
Praktik yang sangat umum untuk kode javascript menulisnya seperti ini:
(function(){
// Some code
})();
Seperti yang Anda lihat, ini adalah deklarasi fungsi anonim, diikuti segera dengan pelaksanaannya. Dengan demikian, semua yang didefinisikan dalam fungsi tidak mungkin diakses dari luar, dan Anda tidak akan mengacaukan ruang lingkup global. Konteks eksekusi fungsi ini akan tetap hidup selama beberapa kode menggunakannya, seperti fungsi bersarang yang didefinisikan dalam konteks ini, yang dapat Anda lewati sebagai panggilan balik atau apa pun.
Javascript adalah bahasa yang sangat berbeda dari C #. Itu bukan berorientasi objek, itu berorientasi prototipe. Ini mengarah pada praktik yang sangat berbeda pada akhirnya.
Bagaimanapun, penutupannya bagus, jadi gunakanlah, bahkan dalam C #!
EDIT: Setelah beberapa diskusi tentang obrolan stackoverflow, saya pikir jawaban ini harus diawali.
Fungsi dalam kode sampel bukan merupakan penutupan. Namun, fungsi ini dapat mendefinisikan variabel lokal dan fungsi bersarang. Semua fungsi bersarang yang menggunakan variabel lokal ini adalah penutupan.
Ini berguna untuk berbagi beberapa data di seluruh rangkaian fungsi tanpa mengacaukan lingkup global. Ini adalah penggunaan penutupan yang paling umum dalam javascript.
Penutupan jauh lebih kuat daripada hanya berbagi beberapa data seperti ini, tapi mari kita bersikap realistis, sebagian besar programmer tidak tahu apa-apa tentang pemrograman fungsional. Dalam C # Anda akan menggunakan kelas atau namespace untuk jenis penggunaan ini, tetapi JS tidak menyediakan fungsi ini.
Anda dapat melakukan jauh lebih banyak dengan penutupan daripada hanya melindungi ruang lingkup global, tetapi ini adalah apa yang akan Anda lihat dalam kode sumber JS.
Mungkin karena implementasi populer dari orientasi objek JavaScript bergantung pada penutupan. Mari kita lihat contoh sederhana:
function counter() {
var value = 0;
this.getValue = function() { return value; }
this.increase = function() { value++; }
}
var myCounter = new counter();
console.log(myCounter.getValue());
myCounter.increase();
console.log(myCounter.getValue());
Metode getValue
dan increase
sebenarnya penutupan, merangkum variabel value
.
Karena banyak perpustakaan yang membuat JavaScript 'tertahankan' menggunakannya.
Lihatlah JQuery , Prototype atau Mootools , hanya untuk tiga nama populer. Masing-masing perpustakaan menyediakan each
metode untuk koleksi mereka sebagai cara iterasi yang lebih disukai, yang menggunakan fungsi iterator. Fungsi itu, ketika mengakses nilai dalam lingkup luar, akan menjadi penutup:
[1,2,3].each(function(item) {
console.log(item);
});
Dan itu tidak berhenti di situ: Callback di Ajax, penanganan event di Ext.js, dll semua mengambil fungsi, dan jika Anda tidak ingin menggembungkan kode Anda dengan 100eds fungsi yang dipanggil tepat sekali, penutupan adalah cara untuk pergi.
console.log
didefinisikan dalam lingkup luar, jadi console
adalah 'variabel bebas'. Dan, mengapa, sebenarnya, for-loop, yang tidak ada bedanya, praktik yang buruk?
Saya setuju dengan jawaban lain bahwa pengkodean "baik" dengan JavaScript lebih bergantung pada penutupan. Namun, selain itu, mungkin hanya pertanyaan tentang berapa lama fitur tersebut telah ada di setiap bahasa. JavaScript pada dasarnya memiliki penutupan sejak implementasi paling awal. C # di sisi lain hanya memilikinya sejak 3.0, yang dirilis dengan Visual Studio 2008.
Banyak programmer C # yang saya temui masih mengerjakan proyek 2.0. Dan bahkan jika mereka bekerja di 3.0 atau 4.0, mereka sering masih menggunakan 2.0 idiom. Saya suka penutupan; semoga mereka akan menjadi lebih banyak digunakan dalam C # sebagai konsep menyebar di antara pengembang C #.
Alasan utamanya adalah karena C # diketik secara statis dan fungsi hanya memiliki akses ke lingkungan tunggal yang telah ditentukan, yang menghambat kegunaan penutupan.
Di JavaScript, di sisi lain, penutupan memungkinkan fungsi berperilaku sebagai metode ketika diakses sebagai properti objek dan menjadi objek kelas satu, mereka juga dapat disuntikkan ke lingkungan yang berbeda yang memungkinkan subrutin beroperasi dalam konteks yang berbeda.
Salah satu alasan saya harus belajar tentang mereka adalah karena ketika Anda mengulang-ulang elemen DOM (atau apa pun juga), Anda ingin dapat "menutup" atau "merangkum" lingkup variabel. Seperti dalam contoh yang diposting di sini: /programming/5606059/how-to-create-closure-in-loop-and-store-it-in-in-variable-for-later-execution