Saya baru-baru ini membandingkan versi json2.js saat ini dengan versi yang saya miliki di proyek saya dan melihat perbedaan dalam cara ekspresi fungsi dibuat dan dijalankan sendiri.
Kode yang digunakan untuk membungkus fungsi anonim dalam tanda kurung dan kemudian menjalankannya,
(function () {
// code here
})();
tapi sekarang ini membungkus fungsi yang dieksekusi secara otomatis dalam tanda kurung.
(function () {
// code here
}());
Ada komentar dari CMS dalam jawaban yang diterima dari Jelaskan sintaks fungsi anonim yang dienkapsulasi JavaScript bahwa "keduanya: (function(){})();
dan (function(){}());
valid."
Saya bertanya-tanya apa bedanya? Apakah yang pertama mengambil memori dengan meninggalkan fungsi global dan anonim? Di mana lokasi tanda kurung?
javascript
syntax
anonymous-function
iife
Kevin Hakanson
sumber
sumber
Jawaban:
Mereka hampir sama.
Yang pertama membungkus tanda kurung di sekitar fungsi untuk membuatnya menjadi ekspresi yang valid dan memanggilnya. Hasil ekspresi tidak ditentukan.
Yang kedua menjalankan fungsi dan tanda kurung di sekitar pemanggilan otomatis menjadikannya ekspresi yang valid. Ini juga mengevaluasi ke tidak terdefinisi.
Saya rasa tidak ada cara yang "benar" untuk melakukannya, karena hasil ungkapannya sama.
sumber
+function(){}()
atau!function(){}()
.-function(){}();
,,!function(){}();
dan pada dasarnya semua operator lain sebelumfunction
juga berfungsi, tetapi saya akan tetap menggunakan versi menggunakan parens). Saya melihat yang pertama lebih banyak daripada yang kedua, dan itu adalah preferensi saya; itu lebih masuk akal bagi saya juga, tapi itu subjektif. FWIW: jsbin.com/ejaqowDalam hal ini tidak masalah. Anda memanggil ekspresi yang menyelesaikan fungsi di definisi pertama, dan menentukan serta segera memanggil fungsi di contoh kedua. Mereka serupa karena ekspresi fungsi pada contoh pertama hanyalah definisi fungsi.
Ada kasus lain yang lebih jelas berguna untuk memanggil ekspresi yang menyelesaikan fungsi:
sumber
foo = function(){alert('hi');}
. Jika tidak ada fungsi, kesalahan dilemparkan.foo
"benar" tetapi bukan fungsi.Tidak ada perbedaan di luar sintaks.
Mengenai kekhawatiran Anda tentang metode kedua untuk melakukannya:
Mempertimbangkan:
(function namedfunc () { ... }())
namedfunc
tidak akan berada dalam cakupan global meskipun Anda memberikan namanya. Hal yang sama berlaku untuk fungsi anonim. Satu-satunya cara untuk mendapatkannya dalam ruang lingkup itu adalah dengan menugaskannya ke variabel di dalam tanda kurung.Tanda kurung luar tidak diperlukan:
Tapi Anda tidak menginginkan deklarasi global itu, bukan?
Jadi intinya adalah:
Dan Anda dapat menguranginya lebih jauh: nama tersebut tidak diperlukan karena tidak akan pernah digunakan (kecuali fungsi Anda rekursif .. dan bahkan Anda dapat menggunakannya
arguments.callee
)Begitulah cara saya memikirkannya (mungkin salah, saya belum membaca spesifikasi ECMAScript). Semoga membantu.
sumber
arguments.callee
tidak digunakan lagi sejak ES5 (dan dilarang dalam mode ketat).Perbedaannya hanya ada karena Douglas Crockford tidak menyukai gaya pertama untuk IIFE ! (seriuosly) Seperti yang Anda lihat di video ini !! .
Satu-satunya alasan keberadaan pembungkusan ekstra
()
{di kedua gaya} adalah untuk membantu membuat bagian kode Ekspresi Fungsi , karena Deklarasi Fungsi tidak bisa langsung dipanggil. Beberapa script / mengecilkan-ers hanya digunakan+
,!
,-
&~
bukannya terlalu kurung. Seperti ini:Dan semua ini persis sama dengan alternatif Anda. Memilih di antara kasus-kasus ini sepenuhnya Anda sendiri & tidak ada bedanya. {Yang
()
menghasilkan 1 Byte File lebih besar ;-)}sumber