!function () {}();
!function () {}();
Jawaban:
Sintaks JavaScript 101. Ini adalah deklarasi fungsi :
function foo() {}
Perhatikan bahwa tidak ada titik koma: ini hanya deklarasi fungsi . Anda perlu doa foo()
,, untuk benar-benar menjalankan fungsinya.
Sekarang, ketika kita menambahkan tanda seru yang tampaknya tidak berbahaya: !function foo() {}
itu mengubahnya menjadi ekspresi . Sekarang merupakan ekspresi fungsi .
Itu !
saja tidak memanggil fungsi, tentu saja, tetapi kita sekarang dapat menempatkan ()
di akhir: !function foo() {}()
yang memiliki prioritas lebih tinggi daripada !
dan langsung memanggil fungsi.
Jadi apa yang penulis lakukan adalah menyimpan byte per fungsi ekspresi; cara penulisan yang lebih mudah dibaca adalah:
(function(){})();
Terakhir, !
jadikan ungkapan itu benar. Hal ini karena secara default semua Iife kembali undefined
, yang meninggalkan kita dengan !undefined
yang true
. Tidak terlalu bermanfaat.
!
mengembalikan boolean, kita semua tahu itu, tetapi poin bagus yang Anda buat adalah bahwa ia juga mengubah pernyataan pernyataan fungsi ke ekspresi fungsi sehingga fungsi tersebut dapat langsung dipanggil tanpa membungkusnya dalam tanda kurung. Tidak jelas, dan jelas maksud si pembuat kode.
var foo =
memecahkan pernyataan / ekspresi ambiguitas dan Anda cukup menulis var foo = function(bar){}("baz");
dll.
Fungsi:
function () {}
tidak menghasilkan apa-apa (atau tidak terdefinisi).
Terkadang kita ingin memanggil fungsi dengan benar saat kita membuatnya. Anda mungkin tergoda untuk mencoba ini:
function () {}()
tetapi menghasilkan SyntaxError
.
Menggunakan !
operator sebelum fungsi menyebabkannya diperlakukan sebagai ekspresi, sehingga kita dapat menyebutnya:
!function () {}()
Ini juga akan kembali kebalikan boolean dari nilai kembali fungsi, dalam hal ini true
, karena !undefined
ini true
. Jika Anda ingin nilai pengembalian yang sebenarnya adalah hasil dari panggilan, maka coba lakukan dengan cara ini:
(function () {})()
!
adalah untuk mengubah deklarasi fungsi menjadi ekspresi fungsi, itu saja.
!function
sintaks
Ada poin yang baik untuk digunakan !
untuk pemanggilan fungsi yang ditandai pada panduan JavaScript airbnb
Secara umum ide untuk menggunakan teknik ini pada file terpisah (modul alias) yang kemudian digabungkan. Peringatan di sini adalah bahwa file seharusnya disatukan oleh alat yang meletakkan file baru di baris baru (yang merupakan perilaku umum untuk sebagian besar alat concat). Dalam hal itu, menggunakan !
akan membantu untuk menghindari kesalahan jika modul yang sebelumnya telah dikenali ketinggalan tanda titik koma, dan itu akan memberikan fleksibilitas untuk menempatkannya dalam urutan apa pun tanpa khawatir.
!function abc(){}();
!function bca(){}();
Akan bekerja sama dengan
!function abc(){}();
(function bca(){})();
tetapi menyimpan satu karakter dan sewenang-wenang terlihat lebih baik.
Dan omong-omong apapun +
, -
, ~
, void
operator memiliki efek yang sama, dalam hal memohon fungsi, pasti jika Anda harus menggunakan sesuatu untuk kembali dari fungsi mereka akan bertindak berbeda.
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
tetapi jika Anda menggunakan pola IIFE untuk satu file satu pemisahan kode modul dan menggunakan alat concat untuk optimasi (yang membuat satu baris satu pekerjaan file), maka konstruksi
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Akan melakukan eksekusi kode aman, sama dengan contoh kode pertama.
Yang ini akan melempar kesalahan karena JavaScript ASI tidak akan dapat melakukan tugasnya.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Satu catatan tentang operator unary, mereka akan melakukan pekerjaan yang sama, tetapi hanya dalam kasus, mereka tidak menggunakan modul pertama. Jadi mereka tidak begitu aman jika Anda tidak memiliki kendali penuh atas urutan penyatuan.
Ini bekerja:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Ini bukan:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Ini mengembalikan apakah pernyataan dapat mengevaluasi ke false. misalnya:
!false // true
!true // false
!isValid() // is not valid
Anda dapat menggunakannya dua kali untuk memaksa nilai ke boolean:
!!1 // true
!!0 // false
Jadi, untuk lebih langsung menjawab pertanyaan Anda:
var myVar = !function(){ return false; }(); // myVar contains true
Sunting: Ini memiliki efek samping dari mengubah deklarasi fungsi ke ekspresi fungsi. Misalnya kode berikut ini tidak valid karena ditafsirkan sebagai deklarasi fungsi yang tidak memiliki pengidentifikasi yang diperlukan (atau nama fungsi ):
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
bisa menghilangkan !
sejenisnya var myVar = function(){ return false; }()
dan fungsi akan mengeksekusi dengan benar dan nilai kembali akan tersentuh.
true
dengan !0
dan false
dengan !1
. Ini menghemat 2 atau 3 karakter.
Hanya untuk menyimpan satu byte data saat kita melakukan minavascript.
pertimbangkan fungsi anonim di bawah ini
function (){}
Untuk menjadikan di atas sebagai fungsi pemanggilan mandiri, kami biasanya akan mengubah kode di atas sebagai
(function (){}())
Sekarang kami menambahkan dua karakter tambahan (,)
selain menambahkan ()
di akhir fungsi yang diperlukan untuk memanggil fungsi. Dalam proses minifikasi biasanya kita fokus untuk mengurangi ukuran file. Jadi kita juga bisa menulis fungsi di atas sebagai
!function (){}()
Masih keduanya adalah fungsi yang dapat dipanggil sendiri dan kami menyimpan byte juga. Alih-alih 2 karakter, (,)
kami hanya menggunakan satu karakter!
! adalah operator TIDAK logis , itu adalah operator boolean yang akan membalikkan sesuatu yang berlawanan.
Meskipun Anda dapat mem-bypass kurung dari fungsi yang dipanggil dengan menggunakan BANG (!) Sebelum fungsi, itu masih akan membalikkan pengembalian, yang mungkin bukan apa yang Anda inginkan. Seperti dalam kasus IEFE, itu akan kembali tidak terdefinisi , yang ketika dibalik menjadi boolean benar.
Alih-alih, gunakan tanda kurung penutup dan BANG ( ! ) Jika perlu.
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
Operator lain yang bekerja ...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Operator Gabungan ...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
Tanda seru membuat fungsi apa pun selalu mengembalikan boolean.
Nilai akhir adalah negasi dari nilai yang dikembalikan oleh fungsi.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Menghilangkan !
contoh-contoh di atas akan menjadi Sintaksis .
function bool() { return true; }() // SyntaxError
Namun, cara yang lebih baik untuk mencapai ini adalah:
(function bool() { return true; })() // true
!
mengubah cara runtime mem-parsing fungsi. Itu membuat runtime memperlakukan fungsi sebagai ekspresi fungsi (dan bukan deklarasi). Ini melakukan ini untuk memungkinkan pengembang untuk segera memanggil fungsi menggunakan ()
sintaks. !
juga akan berlaku sendiri (yaitu negasi) pada hasil memohon ekspresi fungsi.
Ini cara lain untuk menulis IIFE (ekspresi fungsi yang segera dipanggil).
Cara penulisan lainnya -
(function( args ) {})()
sama dengan
!function ( args ) {}();
(function (args) {...})()
sintaksis yang lebih eksplisit dan meninggalkan !function
formulir itu ke alat minifikasi dan kebingungan.
!
akan meniadakan (berlawanan) apapun yang Anda harapkan sebagai hasilnya, yaitu jika Anda miliki
var boy = true;
undefined
boy
true
!boy
false
ketika Anda menelepon boy
, hasilnya Anda akan true
, tetapi saat Anda menambahkan !
saat menelepon boy
, yaitu !boy
, hasil Anda akan false
. Yang dengan kata lain maksud Anda NotBoy , tapi kali ini pada dasarnya merupakan hasil boolean, baik true
atau false
.
Itu adalah hal yang sama yang terjadi pada !function () {}();
ekspresi, menjalankan hanya function () {}();
akan menandai Anda kesalahan, tetapi menambahkan !
tepat di depan function () {}();
ekspresi Anda , membuatnya menjadi kebalikan dari function () {}();
yang seharusnya mengembalikan Anda true
. Contohnya bisa dilihat di bawah ini:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true