Fungsi anonim vs. fungsi bernama terpisah untuk inisialisasi dalam jquery

9

Katakanlah kita memiliki beberapa kode yang digunakan untuk menginisialisasi hal-hal ketika sebuah halaman dimuat dan terlihat seperti ini:

function initStuff() { ...}
...
$(document).ready(initStuff);

Fungsi initStuff hanya dipanggil dari baris ketiga snippet. Tidak akan lagi. Jadi biasanya orang memasukkan ini ke dalam panggilan balik anonim seperti ini:

$(document).ready(function() { 
    //Body of initStuff
});

Memiliki fungsi di lokasi khusus dalam kode tidak benar-benar membantu keterbacaan, karena dengan panggilan siap () membuatnya jelas bahwa ini adalah kode inisialisasi.

Apakah ada alasan lain untuk lebih menyukai yang satu daripada yang lain?

Martin N.
sumber
4
Yang pertama mengacaukan namespace global. Pilih yang kedua.
riwalk

Jawaban:

10

Seperti @ Stargazer712 disebutkan, yang pertama mengacaukan namespace global, jadi yang kedua adalah pemenang IMHO. Sekarang, setelah mengatakan itu, karena Anda menggunakan fungsi anonim dalam contoh kedua, callstack debugger Anda akan sia-sia dan akan mendapatkan hasil yang berbeda tergantung pada debugger yang Anda gunakan. Biasanya, yang akhirnya saya lakukan adalah:

$(document).ready(function MODULE_init() { 
    //Body of initStuff
});

Dengan begitu, namespace global tidak berantakan dan Anda memiliki callstack yang bermanfaat.

Saya cenderung menggunakan konvensi di atas dalam semua definisi fungsi anonim (well, bukan anonim lagi;)). Ini adalah konvensi yang saya temukan saat menjelajah melalui kode JS Firefox.

Sunting: Sekarang setelah mengatakan semua itu, Oliver membawa poin bagus dengan unit test. Di atas dimaksudkan untuk bertindak sebagai pembungkus untuk operasi yang lebih kompleks, bukan untuk menyimpan satu ton kode yang belum diuji.

Demian Brecht
sumber
+1 Untuk menyebutkan debugging. Saya sering melihat penggunaan "name callbacks" (tidak tahu apakah istilah ini benar-benar ada) dalam kode Node.js, jadi saya juga kira itu praktik yang baik.
Oliver Weiler
kangax.github.com/nfe Named Function expressions - Artikel ini memberi tahu Anda segala hal yang ingin Anda ketahui tentangnya.
Sean McMillan
7

Saya akan mengatakan dalam kasus ini mungkin tidak masalah, tetapi jika Anda memiliki fungsi panggilan balik anonim, memanggil fungsi panggilan balik anonim lainnya, saya cenderung menggunakan pendekatan pertama, karena itu membuat kode jauh lebih mudah dibaca dan lebih mudah diikuti.

Berkenaan dengan pengujian unit, pendekatan pertama akan lebih baik, karena Anda akan dapat menguji initstufffungsi secara terpisah.

Oliver Weiler
sumber
Biasanya kami tidak memiliki banyak kode dalam fungsi inisialisasi ini. Mungkin mengambil beberapa data dari beberapa tempat dan hanya itu
Martin N.
3

Saya akan memilih yang pertama, untuk keterbacaan / debugging / pengujian, dll. Anda dapat menghindari masalah kekacauan namespace global dengan hanya membuat namespace lokal untuk semua fungsi pada halaman Anda. Saya menggunakan gaya notasi objek, seperti yang direkomendasikan oleh Paul Irish (lihat slide 13-15 di http://paulirish.com/2009/perf/ )

var MYPAGE = {
  onReady : function(){
  // init code
  },
  someOtherCallback : function(){}
};

jQuery(document).ready(MYPAGE.onReady);
nagagars
sumber
2

Ada juga cara ketiga mendaftar metode init tanpa mengacaukan namespace global yang saya sukai:

jQuery(function(){....});

Ini singkat dan menghindari pencarian dokumen DOM

jQuery(document).ready(function(){...}); 

tidak.

Alex
sumber
+1: Saya pikir ini adalah praktik standar, tetapi untuk menghindari masalah dengan definisi yang saling bertentangan $ saya lebih suka:jQuery(function($) {...});
kevin cline