Dalam javascript, kapan Anda ingin menggunakan ini:
(function(){
//Bunch of code...
})();
lebih dari ini:
//Bunch of code...
Dalam javascript, kapan Anda ingin menggunakan ini:
(function(){
//Bunch of code...
})();
lebih dari ini:
//Bunch of code...
Jawaban:
Ini semua tentang pelingkupan variabel. Variabel yang dideklarasikan dalam fungsi self-executing, secara default, hanya tersedia untuk kode dalam fungsi self-executing. Ini memungkinkan kode ditulis tanpa memperhatikan bagaimana variabel dinamai dalam blok kode JavaScript lainnya.
Misalnya, seperti yang disebutkan dalam komentar oleh Alexander :
(function() {
var foo = 3;
console.log(foo);
})();
console.log(foo);
Ini pertama-tama akan mencatat 3
dan kemudian melemparkan kesalahan pada berikutnya console.log
karena foo
tidak ditentukan.
var
, seperti ini ...function(){ foo=3;}
:? Itu akan mengatur variabel global, kan?
function(){ var foo = 3; alert(foo); }; alert(foo);
Jadi saya masih belum mengerti
Sederhana. Terlihat sangat normal, hampir menghibur:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
Namun, bagaimana jika saya menyertakan pustaka javascript yang sangat berguna ke halaman saya yang menerjemahkan karakter tingkat lanjut ke dalam representasi level dasar mereka?
Tunggu apa?
Maksud saya, jika seseorang mengetik karakter dengan beberapa aksen di atasnya, tetapi saya hanya ingin karakter 'Bahasa Inggris' AZ di program saya? Nah ... karakter Spanyol 'ñ' dan Prancis 'é' dapat diterjemahkan ke dalam karakter dasar 'n' dan 'e'.
Jadi seseorang yang baik telah menulis konverter karakter komprehensif di luar sana yang dapat saya sertakan di situs saya ... saya sertakan.
Satu masalah: ia memiliki fungsi di dalamnya yang disebut 'nama' sama dengan fungsi saya.
Inilah yang disebut tabrakan. Kami memiliki dua fungsi yang dideklarasikan dalam lingkup yang sama dengan nama yang sama. Kami ingin menghindari ini.
Jadi kita perlu mengatur kode kita.
Satu-satunya cara untuk memasukkan kode lingkup dalam javascript adalah dengan membungkusnya dalam suatu fungsi:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Itu mungkin memecahkan masalah kita. Semuanya sekarang tertutup dan hanya dapat diakses dari dalam kurung buka dan tutup kami.
Kami memiliki fungsi dalam suatu fungsi ... yang aneh untuk dilihat, tetapi sepenuhnya legal.
Hanya satu masalah. Kode kami tidak berfungsi. Variabel userName kami tidak pernah bergema ke konsol!
Kami dapat mengatasi masalah ini dengan menambahkan panggilan ke fungsi kami setelah blok kode yang ada ...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
Atau sebelumnya!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
Masalah kedua: Apa peluang nama 'utama' belum digunakan? ... sangat, sangat ramping.
Kami membutuhkan LEBIH pelingkupan. Dan beberapa cara untuk secara otomatis menjalankan fungsi utama () kami.
Sekarang kita sampai pada fungsi eksekusi otomatis (atau menjalankan sendiri, menjalankan sendiri, apa pun).
((){})();
Sintaksinya canggung sebagai dosa. Namun, itu berhasil.
Ketika Anda membungkus definisi fungsi dalam tanda kurung, dan termasuk daftar parameter (set atau tanda kurung lain!) Itu bertindak sebagai panggilan fungsi .
Jadi mari kita lihat kode kita lagi, dengan beberapa sintaks yang dijalankan sendiri:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
Jadi, di sebagian besar tutorial yang Anda baca, Anda sekarang akan dibombardir dengan istilah 'pelaksana mandiri anonim' atau yang serupa.
Setelah bertahun-tahun pengembangan profesional, saya sangat menyarankan Anda untuk memberi nama setiap fungsi yang Anda tulis untuk keperluan debugging.
Ketika terjadi kesalahan (dan itu akan terjadi), Anda akan memeriksa backtrace di browser Anda. Itu selalu lebih mudah untuk mempersempit masalah kode Anda ketika entri dalam jejak tumpukan memiliki nama!
Sangat bertele-tele dan saya harap ini membantu!
:)
Doa diri (juga dikenal sebagai doa otomatis) adalah ketika suatu fungsi dieksekusi segera setelah definisinya. Ini adalah pola inti dan berfungsi sebagai dasar bagi banyak pola pengembangan JavaScript lainnya.
Saya penggemar berat :) karena:
Sangat - (Kenapa kamu harus mengatakan yang baik?)
Lebih lanjut di sini .
Penempatan nama. Lingkup JavaScript adalah tingkat fungsi.
Saya tidak percaya bahwa tidak ada jawaban yang menyebutkan global tersirat.
The (function(){})()
konstruk tidak melindungi terhadap GLOBALS tersirat, yang bagi saya adalah perhatian yang lebih besar, lihat http://yuiblog.com/blog/2006/06/01/global-domination/
Pada dasarnya blok fungsi memastikan semua "global vars" yang Anda definisikan terbatas pada program Anda, itu tidak melindungi Anda dari mendefinisikan global implisit. JSHint atau sejenisnya dapat memberikan rekomendasi tentang cara mempertahankan diri dari perilaku ini.
var App = {}
Sintaks yang lebih ringkas memberikan tingkat perlindungan yang sama, dan dapat dibungkus dalam blok fungsi saat berada di halaman 'publik'. (lihat Ember.js atau SproutCore untuk contoh perpustakaan nyata yang menggunakan konstruk ini)
Sejauh private
properti pergi, mereka agak berlebihan kecuali jika Anda membuat kerangka kerja publik atau perpustakaan, tetapi jika Anda perlu mengimplementasikannya, Douglas Crockford memiliki beberapa ide bagus.
Saya sudah membaca semua jawaban, sesuatu yang sangat penting hilang di sini , saya akan KISS. Ada 2 alasan utama, mengapa saya memerlukan Self-Executing Anonymous Functions, atau lebih baik mengatakan " Ekspresi Fungsi yang Segera Diminta (IIFE) ":
Yang pertama telah dijelaskan dengan sangat baik. Untuk yang kedua, pelajari contoh berikut:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
Perhatian 1: Kami tidak menetapkan fungsi untuk MyClosureObject
, lebih jauh lagi hasil dari memanggil fungsi itu . Waspadai ()
baris terakhir.
Perhatian 2: Apa yang harus Anda ketahui tentang fungsi dalam Javascript adalah bahwa fungsi dalam mendapatkan akses ke parameter dan variabel fungsi, yang didefinisikan di dalamnya.
Mari kita coba beberapa eksperimen:
Saya bisa MyName
menggunakan getMyName
dan berfungsi:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
Pendekatan jujur berikut ini tidak akan berhasil:
console.log(MyClosureObject.MyName);
// undefined
Tetapi saya dapat menetapkan nama lain dan mendapatkan hasil yang diharapkan:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
Sunting: Pada contoh di atas MyClosureObject
dirancang untuk digunakan tanpa new
awalan, oleh karena itu konvensi tidak boleh menggunakan huruf kapital.
Apakah ada parameter dan "Bunch of code" mengembalikan fungsi?
var a = function(x) { return function() { document.write(x); } }(something);
Penutupan. Nilai something
digunakan oleh fungsi yang ditugaskan untuk a
. something
dapat memiliki beberapa nilai yang bervariasi (untuk loop) dan setiap kali memiliki fungsi baru.
var x = something;
dalam fungsi luar lebih x
sebagai parameter, meskipun: imo itu lebih mudah dibaca dengan cara ini ...
x
dan tergantung langsung pada lingkup leksikal, yaitu document.write(something)
...
Isolasi ruang lingkup, mungkin. Sehingga variabel di dalam deklarasi fungsi tidak mencemari namespace luar.
Tentu saja, pada setengah implementasi JS di luar sana, mereka tetap akan melakukannya.
Berikut ini adalah contoh kuat tentang bagaimana fungsi anonim pemanggilan diri bisa berguna.
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
Keluaran: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
Keluaran: 0, 1, 2, 3, 4...
let
ganti var
kasus pertama akan baik-baik saja.
Karena fungsi dalam Javascript adalah objek kelas satu, dengan mendefinisikannya seperti itu, ia secara efektif mendefinisikan "kelas" seperti C ++ atau C #.
Fungsi itu dapat mendefinisikan variabel lokal, dan memiliki fungsi di dalamnya. Fungsi internal (metode instance efektif) akan memiliki akses ke variabel lokal (variabel instance efektif), tetapi mereka akan diisolasi dari sisa skrip.
Fungsi yang dipanggil sendiri dalam javascript:
Ekspresi memohon sendiri dipanggil (dimulai) secara otomatis, tanpa dipanggil. Ekspresi memohon sendiri dipanggil segera setelah dibuat. Ini pada dasarnya digunakan untuk menghindari konflik penamaan serta untuk mencapai enkapsulasi. Variabel atau objek yang dideklarasikan tidak dapat diakses di luar fungsi ini. Untuk menghindari masalah minimisasi (nama file.min) selalu gunakan fungsi yang dieksekusi sendiri.
Fungsi self executing digunakan untuk mengelola ruang lingkup Variabel.
Lingkup variabel adalah wilayah program Anda di mana ia didefinisikan.
Variabel global memiliki cakupan global; itu didefinisikan di mana-mana dalam kode JavaScript Anda dan dapat diakses dari mana saja di dalam skrip, bahkan dalam fungsi Anda. Di sisi lain, variabel yang dideklarasikan dalam suatu fungsi didefinisikan hanya di dalam tubuh fungsi. Mereka adalah variabel lokal, memiliki cakupan lokal dan hanya dapat diakses dalam fungsi itu. Parameter fungsi juga dihitung sebagai variabel lokal dan hanya didefinisikan dalam tubuh fungsi.
Seperti yang ditunjukkan di bawah ini, Anda dapat mengakses variabel global di dalam fungsi Anda dan juga perhatikan bahwa di dalam tubuh suatu fungsi, variabel lokal diutamakan daripada variabel global dengan nama yang sama.
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
Jadi pada dasarnya fungsi mengeksekusi diri memungkinkan kode untuk ditulis tanpa memperhatikan bagaimana variabel dinamai dalam blok kode javascript lainnya.
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
Sebenarnya, fungsi di atas akan diperlakukan sebagai ekspresi fungsi tanpa nama.
Tujuan utama membungkus suatu fungsi dengan kurung tutup dan terbuka adalah untuk menghindari mencemari ruang global.
Variabel dan fungsi di dalam ekspresi fungsi menjadi pribadi (yaitu) mereka tidak akan tersedia di luar fungsi.
Jawaban singkatnya adalah: untuk mencegah polusi pada ruang lingkup Global (atau lebih tinggi).
IIFE (Ekspresi Fungsi yang Segera Diminta) adalah praktik terbaik untuk menulis skrip sebagai plug-in, add-on, skrip pengguna, atau skrip apa pun yang diharapkan bekerja dengan skrip orang lain . Ini memastikan bahwa variabel apa pun yang Anda tetapkan tidak memberikan efek yang tidak diinginkan pada skrip lain.
Ini adalah cara lain untuk menulis ekspresi IIFE. Saya pribadi lebih suka metode berikut ini:
void function() {
console.log('boo!');
// expected output: "boo!"
}();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
Dari contoh di atas, sangat jelas bahwa IIFE juga dapat memengaruhi efisiensi dan kinerja, karena fungsi yang diharapkan dijalankan hanya sekali akan dieksekusi sekali dan kemudian dibuang ke dalam kehampaan untuk selamanya . Ini berarti bahwa deklarasi fungsi atau metode tidak tetap dalam memori.
void
sebelumnya. Saya suka itu.
Pertama, Anda harus mengunjungi MDN IIFE , Sekarang beberapa poin tentang ini
Sepertinya pertanyaan ini sudah dijawab semua sudah siap, tetapi saya tetap akan mengirim masukan saya.
Saya tahu kapan saya ingin menggunakan fungsi self-executing.
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
Fungsi ini memungkinkan saya untuk menggunakan beberapa kode tambahan untuk mendefinisikan atribut childObjects dan properti untuk kode bersih, seperti mengatur variabel yang biasa digunakan atau menjalankan persamaan matematika; Oh! atau pengecekan error. sebagai lawan menjadi terbatas pada sintaks instantiasi objek bersarang ...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
Pengodean secara umum memiliki banyak cara yang tidak jelas dalam melakukan banyak hal yang sama, membuat Anda bertanya-tanya, "Kenapa repot-repot?" Tetapi situasi baru terus bermunculan di mana Anda tidak bisa lagi mengandalkan prinsip dasar / inti saja.
Dengan pertanyaan sederhana Anda: "Dalam javascript, kapan Anda ingin menggunakan ini: ..."
Saya suka jawaban @ken_browning dan @ sean_holding, tetapi berikut ini kasus penggunaan yang tidak saya lihat disebutkan:
let red_tree = new Node(10);
(async function () {
for (let i = 0; i < 1000; i++) {
await red_tree.insert(i);
}
})();
console.log('----->red_tree.printInOrder():', red_tree.printInOrder());
di mana Node.insert adalah beberapa tindakan asinkron.
Saya tidak bisa hanya menelepon menunggu tanpa kata kunci async pada deklarasi fungsi saya, dan saya tidak perlu fungsi bernama untuk digunakan nanti, tetapi perlu menunggu panggilan masukkan itu atau saya memerlukan beberapa fitur kaya lainnya (siapa tahu?) .
IIRC memungkinkan Anda untuk membuat properti dan metode pribadi.