Apa itu konstruksi (fungsi () {}) () dalam JavaScript?


790

Saya dulu tahu apa artinya ini, tapi saya berjuang sekarang ...

Apakah ini pada dasarnya mengatakan document.onload?

(function () {

})();

20
Namun, meskipun Anda akan melihat orang-orang menyebut fungsi ini 'memohon sendiri', itu jelas tidak benar. Istilah iife memiliki keunggulan akurasi.
AakashM

6
Ini memberikan penjelasan yang bagus tentang konstruksi ini. Itu juga tempat istilah "IIFE" berasal. benalman.com/news/2010/11/…
jeremysawesome


2
Untuk penamaan konstruk ini, lihat juga di sini . Baca tentang tujuan konstruk ini , dan penjelasan teknis (juga di sini ). Untuk sintaksis, lihat mengapa kurung diperlukan dan kemana mereka harus pergi .
Bergi

Jawaban:


854

Ini adalah Ekspresi Fungsi Segera-Disebut , atau IIFE singkatnya. Itu dijalankan segera setelah itu dibuat.

Ini tidak ada hubungannya dengan event-handler untuk acara apa pun (seperti document.onload).
Pertimbangkan bagian dalam pasangan kurung pertama: .... itu adalah ekspresi fungsi reguler. Kemudian lihat pasangan terakhir , ini biasanya ditambahkan ke ekspresi untuk memanggil fungsi; dalam hal ini, ungkapan kami sebelumnya.(function(){})();(function(){})();

Pola ini sering digunakan ketika mencoba menghindari polusi namespace global, karena semua variabel yang digunakan di dalam IIFE (seperti dalam fungsi normal lainnya ) tidak terlihat di luar cakupannya.
Inilah sebabnya, mungkin, Anda mengacaukan konstruksi ini dengan event-handler window.onload, karena ini sering digunakan sebagai berikut:

(function(){
  // all your code here
  var foo = function() {};
  window.onload = foo;
  // ...
})();
// foo is unreachable here (it’s undefined)

Koreksi yang disarankan oleh Guffa :

Fungsi dijalankan tepat setelah itu dibuat, bukan setelah diuraikan. Seluruh blok skrip diuraikan sebelum kode apa pun di dalamnya dieksekusi. Juga, kode parsing tidak secara otomatis berarti kode itu dieksekusi, jika misalnya IIFE ada di dalam suatu fungsi maka kode tersebut tidak akan dieksekusi sampai fungsi tersebut dipanggil.

Update Karena ini adalah topik yang cukup populer, layak itu menyebutkan bahwa Iife juga dapat ditulis dengan fungsi panah ES6 ini (seperti gajus memiliki keluar runcing dalam komentar ):

((foo) => {
 // do something with foo here foo
})('foo value')

@ gion_13 apa perbedaan antara fase pembuatan dan fase parse?
akantoword

1
@jlei seperti yang saya lihat, siklus hidup program js meliputi fase berikut: parsing, pembuatan / kompilasi, eksekusi. Meskipun implementasi aktual (dan penamaan :))) mungkin berbeda dari peramban ke peramban, kami dapat menentukan fase-fase ini dalam kode kami dengan memperhatikan kesalahan parsing, mengangkat dan menjalankan kesalahan waktu. Saya pribadi belum menemukan banyak sumber daya karena ini tingkatnya terlalu rendah dan itu bukan sesuatu yang bisa dikontrol oleh programmer. Anda dapat menemukan semacam penjelasan dalam posting SO ini: stackoverflow.com/a/34562772/491075
gion_13

@sam firat semua, ada deklarasi varian dan kata kunci baru. Ini berarti bahwa dalam contoh Anda, Anda membuat instance objek baru yang ditentukan oleh konstruktornya (ekspresi fungsi anonim) dan dipanggil melalui operator baru, bukan dengan memanggil friction seperti pada contoh IIFE. Yakin bahwa fungsi bertindak seperti penutupan untuk isinya tetapi ini jauh berbeda dengan use case.
gion_13

Bagaimana ini mencemari namespace global? foo tidak tersedia di luar fungsi. function(){ var foo = '5'; }
Pankaj

1
@Pankaj - Diambil dengan sendirinya, JS yang bahkan tidak valid secara sintaksis (ini adalah ekspresi fungsi tetapi tidak dalam konteks ekspresi sehingga diperlakukan sebagai kesalahan sintaksis).
Quentin

109

Itu hanya fungsi anonim yang dijalankan segera setelah itu dibuat.

Ini seperti jika Anda menugaskannya ke variabel, dan menggunakannya tepat setelah itu, hanya tanpa variabel:

var f = function () {
};
f();

Di jQuery ada konstruksi serupa yang mungkin Anda pikirkan:

$(function(){
});

Itu adalah bentuk singkat dari pengikatan readyacara:

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

Tetapi dua konstruksi di atas bukanlah IIFE .


83
Dua yang terakhir tidak benar-benar IIFEs, karena mereka dipanggil ketika DOM siap dan tidak segera
svvac

15
@swordofpain: Ya, itu benar, mereka bukan IIFE.
Guffa

@swordofpain mempertimbangkan cuplikan kedua; apakah akan ada nilai tambah () di akhir fungsi dengan mengubahnya menjadi IIFE?
timebandit

Apakah titik koma pada akhirnya diperlukan?
FrenkyB

@FrenkyB Tidak perlu, tidak, tetapi dianjurkan (titik koma sering sebenarnya tidak diperlukan dalam Javascript, tapi ini praktik yang baik). Masing-masing adalah pernyataan yang kebetulan menyertakan fungsi anonim, daripada menjadi deklarasi fungsi.
Ledivin

52

Ekspresi fungsi yang segera dipanggil (IIFE) segera memanggil fungsi. Ini berarti bahwa fungsi tersebut dieksekusi segera setelah definisi selesai.

Tiga kata yang lebih umum:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

Jika tidak ada persyaratan khusus untuk nilai pengembaliannya, maka kita dapat menulis:

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

Atau, bisa juga:

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

Anda bahkan dapat menulis:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required

4
yang terakhir 31.new'adalah sintaks yang tidak valid
cat

9
Mengapa ada begitu banyak cara untuk menulis hal yang sama? !! > _ <Saya tidak suka bahasa ini
Awesome_girl

6
dan pemenangnya adalah;(function(){}());
Roko C. Buljan

Penjelasan preferensi Crockford sangat berguna - menjelaskan perbedaan yang saya lihat di alam, misalnya intisari jQuery tiny-pubsub beralih dari satu versi ke versi lain (Anda dapat melihat perubahan di akhir file) dan saya tidak bisa t mencari tahu mengapa.
icc97

1
@Awesome_girl: Bukan berarti ada banyak cara untuk menulis hal yang sama; JS memiliki sistem tipe longgar dengan operator yang dapat beroperasi pada semua tipe nilai. Anda dapat melakukannya 1 - 1dan Anda bisa melakukannya dengan mudah true - function(){}. Ini hanya satu hal (operator pengurangan infiks) tetapi dengan operan yang berbeda, bahkan tidak masuk akal.

31

Ini mendeklarasikan fungsi anonim, lalu menyebutnya:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

Saya kira "argumen" adalah variabel luar yang dirujuk sebagai "arg" untuk digunakan dalam konteks lokal dalam fungsi?
Dalibor

@ Dalibor argumentsadalah khusus ; Dugaan saya adalah penjawab yang baru saja membalik ke mana nama
cat

29

Maksudnya segera jalankan.

jadi jika saya lakukan:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

Fiddle: http://jsfiddle.net/maniator/LqvpQ/


Contoh kedua:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18

1
Saya tidak mengerti apa yang membuktikannya menarik diri?
Exitos

1
@ Exito karena mengembalikan fungsi itu. Saya akan memberikan contoh kedua.
Naftali alias Neal

sangat mudah dimengerti +1
Adiii

24

Konstruk itu disebut Ekspresi Fungsi Segera Diminta (IIFE) yang artinya dieksekusi segera. Anggap saja sebagai fungsi yang dipanggil secara otomatis ketika juru bahasa mencapai fungsi itu.

Kasus penggunaan yang paling umum:

Salah satu kasus penggunaannya yang paling umum adalah membatasi ruang lingkup variabel yang dibuat via var. Variabel yang dibuat melalui varmemiliki lingkup terbatas pada fungsi sehingga konstruk ini (yang merupakan pembungkus fungsi di sekitar kode tertentu) akan memastikan bahwa ruang lingkup variabel Anda tidak keluar dari fungsi itu.

Dalam contoh berikut, counttidak akan tersedia di luar fungsi yang dipanggil segera yaitu ruang lingkup counttidak akan bocor keluar dari fungsi. Anda harus mendapatkan ReferenceError, haruskah Anda mencoba mengaksesnya di luar fungsi yang dipanggil segera.

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

ES6 Alternatif (Disarankan)

Di ES6, kami sekarang dapat membuat variabel dibuat melalui letdan const. Keduanya diblok-blok (tidak seperti varyang dibatasi fungsi).

Oleh karena itu, alih-alih menggunakan konstruksi IIFE yang kompleks untuk use case yang saya sebutkan di atas, Anda sekarang dapat menulis kode yang lebih sederhana untuk memastikan bahwa ruang lingkup variabel tidak bocor keluar dari blok yang Anda inginkan.

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

Dalam contoh ini, kami digunakan letuntuk mendefinisikan countvariabel yang membuat countterbatas pada blok kode, kami buat dengan kurung keriting {...}.

Saya menyebutnya "Penjara Keriting".


10
Saya suka penamaan Curly Jail . Mungkin itu akan tetap :)
gion_13

15
(function () {
})();

Ini disebut IIFE (Ekspresi Fungsi Segera Diminta). Salah satu pola desain JavaScript yang terkenal, itu adalah jantung dan jiwa dari pola Modul modern. Seperti namanya itu dijalankan segera setelah itu dibuat. Pola ini menciptakan cakupan eksekusi yang terisolasi atau pribadi.

JavaScript sebelum ECMAScript 6 menggunakan scoping lexical, jadi IIFE digunakan untuk mensimulasikan scoping blok. (Dengan pelingkupan blok ECMAScript 6 dimungkinkan dengan pengenalan letdan constkata kunci.) Referensi untuk masalah dengan pelingkupan leksikal

Mensimulasikan pelingkupan blok dengan IIFE

Manfaat kinerja menggunakan Iife adalah kemampuan untuk melewati umum digunakan objek global seperti window, document, dll sebagai argumen dengan mengurangi ruang lingkup lookup. (Ingat JavaScript mencari properti di lingkup lokal dan meningkatkan rantai sampai lingkup global). Jadi mengakses objek global dalam lingkup lokal mengurangi waktu pencarian seperti di bawah ini.

(function (globalObj) {
//Access the globalObj
})(window);

Terima kasih telah menyediakan intisari untuk memahami tanda kurung kedua di IIFE. Juga untuk memperjelas manfaat waktu pencarian dari variabel global dengan mendefinisikannya dalam definisi
Arsal

11

Tidak, konstruksi ini hanya menciptakan ruang lingkup untuk penamaan. Jika Anda memecahnya di beberapa bagian Anda dapat melihat bahwa Anda memiliki eksternal

(...)();

Itu adalah doa fungsi. Di dalam kurung Anda memiliki:

function() {}

Itu adalah fungsi anonim. Segala sesuatu yang dideklarasikan dengan var di dalam konstruk akan terlihat hanya di dalam konstruk yang sama dan tidak akan mencemari namespace global.


11

Ini adalah Ekspresi Fungsi yang Segera Diminta dalam Javascript:

Untuk memahami IIFE di JS, mari jabarkan:

  1. Ekspresi : Sesuatu yang mengembalikan nilai
    Contoh: Coba ikuti di konsol chrome. Ini adalah ekspresi dalam JS.
a = 10 
output = 10 
(1+3) 
output = 4
  1. Ekspresi Fungsi :
    Contoh:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

Cara kerja ekspresi fungsi:
- Ketika mesin JS berjalan untuk pertama kalinya (Konteks Eksekusi - Buat Fase), fungsi ini (di sisi kanan = atas) tidak dijalankan atau disimpan dalam memori. Variabel 'salam' diberi nilai 'tidak terdefinisi' oleh mesin JS.
- Selama eksekusi (Konteks Eksekusi - fase Eksekusi), objek funtion dibuat dengan cepat ( belum dieksekusi ), akan ditugaskan ke variabel 'sapa' dan dapat dipanggil menggunakan 'salam (' nama samaran ')'.

3. Ekspresi Funtion Segera Diminta:

Contoh:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

Cara IIFE bekerja :
- Perhatikan '()' segera setelah deklarasi fungsi. Setiap objek funtion memiliki properti 'CODE' yang melekat padanya yang dapat dipanggil. Dan kita bisa menyebutnya (atau memintanya) menggunakan kawat gigi '()'.
- Jadi di sini, selama eksekusi (Execution Context - Execute Phase), objek fungsi dibuat dan dieksekusi pada saat yang sama - Jadi sekarang, variabel ucapan, alih-alih memiliki objek funtion, memiliki nilai balik (string)

Usecase khas IIFE di JS:

Pola IIFE berikut ini cukup umum digunakan.

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • kami melakukan dua hal di sini. a) Membungkus ekspresi fungsi kami di dalam kurung kurawal (). Ini berlaku untuk memberitahu parser sintaks apa pun yang ditempatkan di dalam () adalah ekspresi (ekspresi fungsi dalam kasus ini) dan merupakan kode yang valid.
    b) Kami menjalankan fungsi ini pada saat yang sama menggunakan () di akhir itu.

Jadi fungsi ini dibuat dan dijalankan pada saat yang sama (IIFE).

Penggunaan penting untuk IIFE:

IIFE menjaga keamanan kode kita.
- IIFE, sebagai fungsi, memiliki konteks eksekusi sendiri, yang berarti semua variabel yang dibuat di dalamnya adalah lokal untuk fungsi ini dan tidak dibagi dengan konteks eksekusi global.

Misalkan saya memiliki file JS lain (test1.js) yang digunakan dalam aplikasi saya bersama dengan iife.js (lihat di bawah).

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

Jadi IIFE membantu kita menulis kode aman di mana kita tidak bertabrakan dengan objek global secara tidak sengaja.


Jika kita membuat fungsi di dalam IIFE bagaimana kita mengaksesnya di beberapa file js atau jsx lainnya yaitu dalam komponen reaksi.
batu batu

Meskipun kami tidak menggunakan IIFE, variabel ucapan tidak akan bertabrakan pada variabel ucapan global. Jadi apa untungnya di sana?
Willy David Jr

6

Itu adalah fungsi anonim yang dapat digunakan sendiri .

Lihatlah penjelasan W3Schools tentang fungsi self-invaging .

Ekspresi fungsi dapat dibuat "memohon sendiri".

Ekspresi memohon sendiri dipanggil (dimulai) secara otomatis, tanpa dipanggil.

Ekspresi fungsi akan dieksekusi secara otomatis jika ekspresi diikuti oleh ().

Anda tidak dapat menjalankan sendiri deklarasi fungsi.


3
(function named(){console.log("Hello");}());<- mengeksekusi fungsi bernama fungsi
bryc

@ bryc mengapa Anda memberi nama fungsi yang tidak membutuhkan nama.
RicardoGonzales

2
@RicardoGonzales Rekursi Saya kira
bryc

5

Ini adalah fungsi anonim yang aktif sendiri. Ini dieksekusi saat didefinisikan. Yang berarti fungsi ini didefinisikan dan memanggil dirinya sendiri segera setelah definisi.

Dan penjelasan sintaksnya adalah: Fungsi dalam ()tanda kurung pertama adalah fungsi yang tidak memiliki nama dan dengan ();tanda kurung berikutnya Anda dapat memahami bahwa itu dipanggil pada saat itu didefinisikan. Dan Anda bisa memberikan argumen apa pun dalam ()tanda kurung kedua yang akan diambil dalam fungsi yang ada di tanda kurung pertama. Lihat contoh ini:

(function(obj){
    // Do something with this obj
})(object);

Di sini 'objek' yang Anda lewati akan dapat diakses di dalam fungsi dengan 'obj', karena Anda meraihnya dalam tanda tangan fungsi.


2
Pertanyaan ini sudah memiliki jawaban yang diterima dan jawaban Anda tidak menambahkan apa pun yang belum dicakup oleh jawaban yang diterima. Karenanya, sama sekali tidak perlu menulis jawaban ini.
Aadit M Shah

3
Saya suka membaca beberapa jawaban, terkadang ungkapan yang satu atau yang lain membuat perbedaan.

Saya pikir itu ditambahkan karena memberi tahu saya untuk apa kurung kedua itu. Setidaknya lebih jelas di sini yang saya lihat.
johnny

Teman saya. Kedua ujung sampel IIFE memiliki parameter, dan pemetaan antara keduanya dibuat jelas.
Stephen W. Wright

4

Mulai di sini:

var b = 'bee';
console.log(b);  // global

Masukkan fungsi dan tidak lagi mendunia - tujuan utama Anda.

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

Segera panggil fungsi - oops:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

Gunakan tanda kurung untuk menghindari kesalahan sintaksis:

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

Anda dapat mengabaikan nama fungsi:

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

Tidak perlu lebih rumit dari itu.


2
Kesalahan sintaks berbicara tentang fungsi panah. Seperti yang saya pahami, ini adalah fitur baru js, dan tidak ada beberapa tahun yang lalu, tetapi IIFE melakukannya. Jadi, kurung mungkin awalnya digunakan untuk menghindari kesalahan sintaks, tetapi berbeda?
JCarlosR

Bisakah Anda menjawab pertanyaan @JCarlos? Saat ia dengan tepat menunjukkan bahwa IIFE datang jauh sebelum fungsi panah, itu akan membantu memahami mengapa pembungkus diperlukan.
Script47

@ Script47 Saya tidak punya jawaban untuk pertanyaan JCarlos di komentar. Anda dapat merumuskan pertanyaan baru dan mempostingnya, dan saya yakin Anda akan mendapatkan jawaban yang bagus.
Jim Flood

@ JCarlos ketika saya menjalankan salah satu yang melempar kesalahan, saya benar-benar mendapatkan Uncaught SyntaxError: Unexpected token )daripada menyebutkan fungsi panah. Bisakah Anda berbagi biola dengan itu melempar kesalahan fungsi panah?
Script47

2

Menjalankan fungsi anonim. Ini dieksekusi segera setelah dibuat.

Salah satu contoh pendek dan dummy di mana ini berguna adalah:

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

Jadi, alih-alih membuat daftar setiap kali, Anda membuatnya hanya sekali (kurang overhead).


1
Seperti yang tertulis, pencarian Anda membangun kembali daftar pada setiap doa. Untuk menghindarinya, Anda perlu (1) membuat daftar dan (2) mengembalikan fungsi pencarian sebagai penutup yang memiliki akses ke daftar yang baru saja Anda buat. Ini dapat Anda lakukan dengan mudah menggunakan formulir pemanggilan mandiri anonim. Lihat jsfiddle.net/BV4bT .
George

dapatkah kau jelaskan ... kurang overhead .. aku tidak mengerti bagian ini
HIRA THAKUR

2
Overhead berarti setiap pekerjaan yang dilakukan yang tidak perlu. Mempopulasikan sebuah array pada setiap pemanggilan fungsi tidak perlu, itu sebabnya sebuah array dalam contoh diisi oleh self-exec. fungsi anonim untuk pertama kalinya saja. Namun, sepertinya saya telah membuat kesalahan dalam jawaban saya sendiri, lihat tautan di komentar George untuk contoh yang tepat.
usoban

2

Fungsi self-executing biasanya digunakan untuk merangkum konteks dan menghindari kolusi nama. Variabel apa pun yang Anda tetapkan di dalam (function () {..}) () tidak bersifat global.

Kode

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

menghasilkan output ini:

2
1

Dengan menggunakan sintaks ini Anda menghindari bertabrakan dengan variabel global yang dideklarasikan di tempat lain dalam kode JavaScript Anda.


1
Benar, output akan menjadi 2 dan kemudian 1 karena myVar akan dijalankan pertama
Dalibor

1
Penjelasan Anda berjalan dengan baik dalam menjelaskan lingkup fungsi tetapi gagal menjelaskan mengapa itu dieksekusi segera. Menugaskannya ke variabel mengalahkan diri sendiri dan mungkin juga bermaksud bahwa itu dapat dieksekusi lebih dari sekali. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Akan memiliki hasil yang sama.
domenicr

2

Ini disebut IIFE - Ekspresi Fungsi Segera Diminta. Berikut adalah contoh untuk menunjukkan sintaks dan penggunaannya. Ini digunakan untuk lingkup penggunaan variabel hanya sampai fungsi dan bukan di luar.

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

1

IIFE (Ekspresi fungsi yang segera dipanggil) adalah fungsi yang dieksekusi segera setelah skrip dimuat dan hilang.

Pertimbangkan fungsi di bawah ini yang ditulis dalam file bernama iife.js

(function(){
       console.log("Hello Stackoverflow!");
   })();

Kode di atas ini akan dieksekusi segera setelah Anda memuat iife.js dan akan mencetak ' Hello Stackoverflow! konsol 'pada alat pengembang'.

Untuk penjelasan terperinci, lihat Ekspresi Fungsi Segera-Diminta (IIFE)


1

Satu lagi use case adalah memoisasi di mana objek cache tidak bersifat global:

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();

0

Ekspresi fungsi yang segera dipanggil (IIFE) adalah fungsi yang dieksekusi segera setelah itu dibuat. Itu tidak memiliki koneksi dengan peristiwa atau eksekusi asinkron. Anda dapat mendefinisikan IIFE seperti yang ditunjukkan di bawah ini:

(function() {
     // all your code here
     // ...
})();

Pasangan pertama tanda kurung fungsi () {...} mengubah kode di dalam tanda kurung menjadi ekspresi. Pasangan tanda kurung kedua memanggil fungsi yang dihasilkan dari ekspresi.

An IIFEjuga dapat digambarkan sebagai fungsi anonim yang aktif sendiri. Penggunaannya yang paling umum adalah untuk membatasi ruang lingkup variabel yang dibuat melalui var atau untuk merangkum konteks untuk menghindari tabrakan nama.


0

Alasan self-membangkitkan fungsi anonim digunakan adalah mereka tidak boleh dipanggil oleh kode lain karena mereka "mengatur" kode yang dimaksudkan untuk dipanggil IS (bersama dengan memberikan ruang lingkup ke fungsi dan variabel).

Dengan kata lain, mereka seperti program yang "membuat kelas ', pada awal program. Setelah mereka instantiated (secara otomatis), satu-satunya fungsi yang tersedia adalah yang dikembalikan oleh fungsi anonim. Namun, semua yang lain' fungsi-fungsi tersembunyi masih ada, bersama dengan status apa pun (variabel ditetapkan selama pembuatan lingkup).

Sangat keren.


0

Kode berikut:

(function () {

})();

disebut ekspresi fungsi yang segera dipanggil (IIFE).

Ini disebut ekspresi fungsi karena ( yourcode )operator dalam Javascript memaksanya menjadi ekspresi. Perbedaan antara ekspresi fungsi dan deklarasi fungsi adalah sebagai berikut:

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

Ekspresi hanyalah sekelompok kode yang dapat dievaluasi menjadi nilai tunggal . Dalam kasus ekspresi dalam contoh di atas nilai ini adalah objek fungsi tunggal .

Setelah kami memiliki ekspresi yang mengevaluasi ke objek fungsi kami kemudian dapat segera memanggil objek fungsi dengan ()operator. Sebagai contoh:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

Mengapa ini berguna?

Ketika kita berhadapan dengan basis kode besar dan / atau ketika kita mengimpor berbagai pustaka, peluang penamaan konflik meningkat. Ketika kita menulis bagian-bagian tertentu dari kode kita yang terkait (dan dengan demikian menggunakan variabel yang sama) di dalam IIFE semua variabel dan nama fungsi di-scoped ke kurung fungsi IIFE . Ini mengurangi kemungkinan penamaan konflik dan memungkinkan Anda menamainya dengan lebih ceroboh (mis. Anda tidak harus mengawasinya).


0

Dalam sintaks ES6 (memposting untuk saya sendiri, karena saya terus mendarat di halaman ini mencari contoh cepat):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)

0

Fungsi ini disebut fungsi memohon sendiri. Fungsi self-invoking (juga disebut self-executing) adalah fungsi tanpa nama (anonim) yang dipanggil (Dipanggil) segera setelah definisinya. Baca lebih lanjut di sini

Apa fungsi-fungsi ini lakukan adalah bahwa ketika fungsi didefinisikan, fungsi segera dipanggil, yang menghemat waktu dan baris kode tambahan (dibandingkan dengan memanggilnya pada baris terpisah).

Berikut ini sebuah contoh:

(function() {
    var x = 5 + 4;
    console.log(x);
})();



0

Ini adalah ekspresi fungsi, singkatan dari Immediately Invoked Function Expression (IIFE). IIFE hanyalah sebuah fungsi yang dieksekusi segera setelah itu dibuat. Jadi insted dari fungsi harus menunggu sampai dipanggil untuk dieksekusi, IIFE dieksekusi segera. Mari kita membangun IIFE dengan contoh. Misalkan kita memiliki fungsi add yang mengambil dua bilangan bulat sebagai args dan mengembalikan jumlah mari kita buat fungsi add menjadi IIFE,

Langkah 1: Tentukan fungsi

function add (a, b){
    return a+b;
}
add(5,5);

Langkah2: Panggil fungsi dengan membungkus seluruh deklarasi fungsi menjadi tanda kurung

(function add (a, b){
    return a+b;
})
//add(5,5);

Langkah 3: Untuk membuka fungsi dengan segera, cukup hapus teks 'tambah' dari panggilan.

(function add (a, b){
    return a+b;
})(5,5);

Alasan utama untuk menggunakan IFFE adalah untuk mempertahankan ruang lingkup pribadi dalam fungsi Anda. Di dalam kode javascript Anda ingin memastikannya, Anda tidak mengabaikan variabel global apa pun. Terkadang Anda mungkin secara tidak sengaja mendefinisikan variabel yang menimpa variabel global. Mari kita coba dengan contoh. misalkan kita memiliki file html bernama iffe.html dan kode di dalam tag tubuh adalah-

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Nah, kode di atas akan mengeksekusi tanpa pertanyaan, sekarang asumsikan Anda mendeklarasikan variabel bernama dokumen yang tidak disengaja atau disengaja.

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

Anda akan berakhir di SyntaxError : pernyataan ulang dokumen properti global yang tidak dapat dikonfigurasi.

Tetapi jika keinginan Anda adalah untuk mendeklarasikan documet nama variabel, Anda dapat melakukannya dengan menggunakan IFFE.

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Keluaran:

masukkan deskripsi gambar di sini

Mari kita coba dengan contoh lain, misalkan kita memiliki objek kalkulator seperti di bawah-

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

Yah itu berfungsi seperti pesona, bagaimana jika kita tidak sengaja menetapkan ulang nilai objek kalkulator.

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

ya Anda akan berakhir dengan TypeError: calculator.mul bukan fungsi iffe.html

Tetapi dengan bantuan IFFE kita dapat membuat ruang lingkup pribadi di mana kita dapat membuat kalkulator nama variabel lain dan menggunakannya;

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

Keluaran: masukkan deskripsi gambar di sini


-1

Saya pikir 2 set kurung membuatnya agak membingungkan tapi saya melihat penggunaan lain dalam contoh Google, mereka menggunakan sesuatu yang serupa, saya harap ini akan membantu Anda memahami lebih baik:

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

jadi jika windows.apptidak didefinisikan, maka window.app = {}segera dieksekusi, jadi window.appditugaskan {}selama evaluasi kondisi, sehingga hasilnya keduanya appdan window.appsekarang menjadi {}, jadi output konsol adalah:

Object {}
Object {}

-1

Biasanya, kami tidak menjalankan fungsi segera setelah kami menulisnya di program. Dalam istilah yang sangat sederhana, ketika Anda memanggil fungsi tepat setelah pembuatannya, itu disebut IIFE - nama mewah.


-1

Biasanya, kode JavaScript memiliki cakupan global dalam aplikasi. Ketika kami mendeklarasikan variabel global di dalamnya, ada peluang untuk menggunakan variabel duplikat yang sama di beberapa area pengembangan lainnya untuk beberapa tujuan lain. Karena duplikasi ini mungkin ada beberapa kesalahan. Jadi kita bisa menghindari variabel global ini dengan menggunakan ekspresi fungsi yang langsung dipanggil, ekspresi ini adalah ekspresi yang mengeksekusi sendiri. Ketika kita membuat kode kita di dalam IIFE ini variabel global ekspresi akan seperti cakupan lokal dan variabel lokal.

Dua cara kita dapat membuat IIFE

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

ATAU

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

Dalam cuplikan kode di atas, " var app " adalah variabel lokal sekarang.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.