Pendeknya
Ringkasan
Dalam bentuknya yang paling sederhana, teknik ini bertujuan untuk membungkus kode di dalam lingkup fungsi .
Ini membantu mengurangi kemungkinan:
- berbenturan dengan aplikasi / perpustakaan lain
- ruang lingkup unggul (kemungkinan terbesar) yang berpolusi
Itu tidak mendeteksi ketika dokumen sudah siap - itu bukan semacam document.onload
atau tidakwindow.onload
Umumnya dikenal sebagai Immediately Invoked Function Expression (IIFE)
atau Self Executing Anonymous Function
.
Kode Dijelaskan
var someFunction = function(){ console.log('wagwan!'); };
(function() { /* function scope starts here */
console.log('start of IIFE');
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})(); /* function scope ends */
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Dalam contoh di atas, variabel apa pun yang didefinisikan dalam fungsi (yaitu dideklarasikan menggunakan var
) akan menjadi "pribadi" dan dapat diakses dalam lingkup fungsi HANYA (seperti yang dikatakan Vivin Paliath). Dengan kata lain, variabel-variabel ini tidak terlihat / terjangkau di luar fungsi. Lihat demo langsung .
Javascript memiliki fungsi pelingkupan. "Parameter dan variabel yang didefinisikan dalam suatu fungsi tidak terlihat di luar fungsi, dan bahwa variabel yang didefinisikan di mana saja dalam suatu fungsi terlihat di mana-mana dalam fungsi." (dari "Javascript: The Good Parts").
Keterangan lebih lanjut
Kode Alternatif
Pada akhirnya, kode yang diposting sebelumnya juga dapat dilakukan sebagai berikut:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
};
myMainFunction(); // I CALL "myMainFunction" FUNCTION HERE
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Lihat demo langsung .
Akar
Iterasi 1
Suatu hari, seseorang mungkin berpikir "pasti ada cara untuk menghindari penamaan 'myMainFunction', karena semua yang kita inginkan adalah menjalankannya dengan segera."
Jika Anda kembali ke dasar-dasarnya, Anda mengetahui bahwa:
expression
: sesuatu yang mengevaluasi suatu nilai. yaitu3+11/x
statement
: baris kode melakukan sesuatu TETAPI itu tidak mengevaluasi nilai. yaituif(){}
Demikian pula, ekspresi fungsi mengevaluasi suatu nilai. Dan satu konsekuensi (saya kira?) Adalah mereka dapat langsung dipanggil:
var italianSayinSomething = function(){ console.log('mamamia!'); }();
Jadi contoh kita yang lebih kompleks menjadi:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
}();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Lihat demo langsung .
Iterasi 2
Langkah selanjutnya adalah pikiran "mengapa var myMainFunction =
kita harus menggunakan itu saja !?"
Jawabannya sederhana: coba hapus ini, seperti di bawah ini:
function(){ console.log('mamamia!'); }();
Lihat demo langsung .
Ini tidak akan berfungsi karena "deklarasi fungsi tidak dapat dimasuki" .
Kuncinya adalah dengan menghapus var myMainFunction =
kita mengubah ekspresi fungsi menjadi pernyataan fungsi . Lihat tautan di "Sumberdaya" untuk detail lebih lanjut tentang ini.
Pertanyaan selanjutnya adalah "mengapa saya tidak bisa menyimpannya sebagai ekspresi fungsi dengan sesuatu selain var myMainFunction =
?
Jawabannya adalah "Anda bisa", dan sebenarnya ada banyak cara Anda bisa melakukan ini: menambahkan a +
, a !
, a -
, atau mungkin membungkus sepasang tanda kurung (seperti yang sekarang dilakukan oleh konvensi), dan lebih banyak lagi saya percaya. Sebagai contoh:
(function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.
atau
+function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console
atau
-function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console
Jadi, setelah modifikasi yang relevan ditambahkan ke apa yang dulunya "Kode Alternatif" kami, kami kembali ke kode yang sama persis seperti yang digunakan dalam contoh "Kode Dijelaskan"
var someFunction = function(){ console.log('wagwan!'); };
(function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
Baca lebih lanjut tentang Expressions vs Statements
:
Lingkup Demistifikasi
Satu hal yang mungkin bertanya-tanya adalah "apa yang terjadi ketika Anda TIDAK mendefinisikan variabel 'benar' di dalam fungsi - yaitu melakukan tugas sederhana sebagai gantinya?"
(function() {
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
myOtherFunction = function(){ /* oops, an assignment instead of a declaration */
console.log('haha. got ya!');
};
})();
myOtherFunction(); // reachable, hence works: see in the console
window.myOtherFunction(); // works in the browser, myOtherFunction is then in the global scope
myFunction(); // unreachable, will throw an error, see in the console
Lihat demo langsung .
Pada dasarnya, jika suatu variabel yang tidak dideklarasikan dalam lingkupnya saat ini diberi nilai, maka "lihat rantai lingkup terjadi sampai ia menemukan variabel atau mengenai lingkup global (pada titik mana ia akan membuatnya)".
Ketika di lingkungan browser (vs lingkungan server seperti nodejs) lingkup global ditentukan oleh window
objek. Karenanya kita bisa melakukannya window.myOtherFunction()
.
Kiat "Praktik yang baik" pada topik ini adalah untuk selalu digunakan var
saat menentukan apa pun : apakah itu angka, objek, atau fungsi, & bahkan saat dalam lingkup global. Ini membuat kode lebih sederhana.
catatan:
- javascript tidak memiliki
block scope
(Pembaruan: ruang lingkup variabel lokal ditambahkan dalam ES6 .)
- javascript hanya memiliki
function scope
& global scope
( window
cakupan di lingkungan browser)
Baca lebih lanjut tentang Javascript Scopes
:
Sumber daya
Langkah selanjutnya
Setelah Anda mendapatkan IIFE
konsep ini , itu mengarah ke module pattern
, yang biasanya dilakukan dengan memanfaatkan pola IIFE ini. Selamat bersenang-senang :)