JavaScript'te (function () {}) () yapısı nedir?


790

Bunun ne anlama geldiğini biliyordum, ama şimdi mücadele ediyorum ...

Bu temelde diyor document.onloadmu?

(function () {

})();

20
btw, bu işlevi 'kendi kendini çağıran' olarak adlandırılanları görecek olsanız da, bu kesinlikle doğru değil. İife terimi doğruluk avantajına sahiptir.
AakashM

6
Bu, bu yapının büyük bir açıklamasını verir. Ayrıca "IIFE" terimi de burada ortaya çıkmıştır. benalman.com/news/2010/11/…
jeremysawesome


2
Bu yapının adlandırılması için buraya da bir göz atın . Bu yapının amacı ve teknik bir açıklama ( burada da ) hakkında bilgi edinin . Sözdizimi için, parantezin neden gerekli olduğuna ve nereye gitmeleri gerektiğine bir göz atın .
Bergi

Yanıtlar:


854

Bu bir var Hemen-çağrılan Fonksiyon İfade veya hayattan kısaca. Oluşturulduktan hemen sonra yürütülür.

Herhangi bir olay (örneğin document.onload) için herhangi bir olay işleyici ile ilgisi yoktur .
İlk parantez çifti içindeki parçayı düşünün: .... düzenli bir işlev ifadesidir. Sonra son çifte bakın , bu normalde bir işlevi çağırmak için bir ifadeye eklenir; bu durumda, bizim önceki ifademiz.(function(){})();(function(){})();

Bu model genellikle global ad alanını kirletmekten kaçınmaya çalışırken kullanılır, çünkü IIFE içinde kullanılan tüm değişkenler (diğer normal işlevlerde olduğu gibi) kapsamı dışında görünmez.
Bu nedenle, belki de, bu yapıyı bir olay işleyicisi ile karıştırdınız window.onload, çünkü genellikle şu şekilde kullanılır:

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

Guffa tarafından önerilen düzeltme :

İşlev, ayrıştırıldıktan sonra değil, oluşturulduktan hemen sonra yürütülür. Komut dosyası bloğunun tamamı, içindeki herhangi bir kod yürütülmeden ayrıştırılır. Ayrıca, kodun ayrıştırılması otomatik olarak yürütüldüğü anlamına gelmez, örneğin IIFE bir işlevin içindeyse, işlev çağrılıncaya kadar yürütülmez.

Güncelleme Bu oldukça popüler bir konu olduğundan, IIFE'lerin ES6'nın ok işlevi ile de yazılabileceğini belirtmek gerekir ( Gajus'un bir yorumda işaret ettiği gibi ):

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

@ gion_13 oluşturma aşaması ile ayrıştırma aşaması arasındaki fark nedir?
akantoword

1
@jlei benim gördüğüm şekilde, bir js programının yaşam döngüsü şu aşamaları içerir: ayrıştırma, oluşturma / derleme, yürütme. Gerçek uygulama (ve adlandırma :)) tarayıcıdan tarayıcıya farklılık gösterse de hataları, kaldırma ve çalışma süresi hatalarını izleyerek kodumuzdaki bu aşamaları belirleyebiliriz. Şahsen bu konuda çok fazla kaynak bulamadım çünkü çok düşük bir seviye ve programcının kontrol edebileceği bir şey değil. Bu SO yazısında bir çeşit açıklama bulabilirsiniz: stackoverflow.com/a/34562772/491075
gion_13

@sam firat, varianle bildirimi ve yeni anahtar kelime var. Bu, örneğinizde, kurucusu (anonim işlev ifadesi) tarafından tanımlanan yeni bir obiect oluşturduğunuzu ve IIF örneğinde olduğu gibi finction'ı çağırmakla değil, yeni operatör aracılığıyla çağrıldığınız anlamına gelir. Bu işlevin içeriği için bir kapak görevi gördüğünden emin olabilirsiniz, ancak bu çok farklı bir kullanım örneğidir.
gion_13

Bu küresel isim alanını nasıl kirletiyor? foo zaten fonksiyonun dışında kullanılamaz. function(){ var foo = '5'; }
Pankaj

1
@Pankaj - Tek başına ele alındığında, sözdizimsel olarak geçerli olmayan JS bile değildir (bir işlev ifadesidir, ancak ifade bağlamında değildir, bu nedenle sözdizimi hatası olarak değerlendirilir).
Quentin

109

Bu, oluşturulduktan hemen sonra yürütülen anonim bir işlevdir.

Tıpkı bir değişkene atadığınız ve hemen sonra, sadece değişken olmadan kullandığınız gibi:

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

JQuery'de aklınıza gelebilecek benzer bir yapı vardır:

$(function(){
});

readyOlayı bağlamanın kısa biçimi budur :

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

Ancak yukarıdaki iki yapı IIFE değildir .


83
DOM hazır olduğunda hemen
svvac

15
@swordofpain: Evet, doğru, IIFE değiller.
Guffa

@swordofpain ikinci pasajı dikkate alınarak; fonksiyonun sonuna bir IIFE'ye dönüştürülerek add () öğesinde herhangi bir değer olur mu?
timebandit

Sonundaki noktalı virgül gerekli mi?
FrenkyB

@FrenkyB Gerekli değil, hayır, ancak teşvik edilir (noktalı virgül aslında Javascript'te gerekli değildir, ancak iyi bir uygulamadır). Bunların her biri, işlev bildirimleri yerine anonim işlevler içeren ifadelerdir.
Ledivin

52

Hemen çağrılan bir işlev ifadesi (IIFE) hemen bir işlevi çağırır. Bu, işlevin tanımın tamamlanmasından hemen sonra yürütüldüğü anlamına gelir.

Üç yaygın kelime daha:

// 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.');
}();

Dönüş değeri için özel bir gereklilik yoksa, şunu yazabiliriz:

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

Alternatif olarak, şunlar olabilir:

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

Hatta yazabilirsiniz:

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

4
sonuncusu 31.new'geçersiz sözdizimi
cat

9
Neden aynı şeyi yazmanın birçok yolu var? !! > _ <Bu dili sevmiyorum
Awesome_girl

6
aaand kazanan;(function(){}());
Roko C. Buljan

Crockford tercih açıklaması çok yararlıydı - vahşi doğada gördüğüm farklılıkları açıklıyor, örneğin jQuery tiny-pubsub gist bir sürümden diğerine geçti (dosyanın sonunda değişikliği görebilirsiniz) ve yapamadım nedenini anlayamıyorum.
icc97

1
@Awesome_girl: Aynı şeyi yazmanın birçok yolu olmadığı değil; JS'nin herhangi bir değer türünde çalışabilen işleçleri olan gevşek bir sisteme sahip olması. Yapabilirsin 1 - 1ve kolayca yapabilirsin true - function(){}. Bu sadece bir şeydir (bir infix çıkarma operatörü), ancak farklı, hatta saçma işlenenlerle.

31

Anonim bir işlev bildirir ve çağırır:

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

Sanırım "arguments" işlevi içinde yerel bağlamda kullanılacak "arg" olarak adlandırılan dış değişkenler nelerdir?
Dalibor

@Dalibor argumentsolan özel ; tahminim cevap veren isimlerin nereye gittiğini
kedi

29

Yani derhal idam.

eğer öyleyse:

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

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


İkinci Örnek:

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

alert(val); //18

1
Anlamadım, bu kendini çağrıştırıyor ne kanıtlıyor?
Exitos

1
@Exitos çünkü bu işlevi döndürür. İkinci bir örnek vereceğim.
Naftali aka Neal

anlamak çok kolay +1
Adiii

24

Bu yapıya derhal çağrıldığı Fonksiyon İfadesi (IIFE) denir, yani derhal yürütülür. Bunu, yorumlayıcı bu işleve ulaştığında otomatik olarak çağrılan bir işlev olarak düşünün.

En Yaygın Kullanım:

En yaygın kullanım durumlarından biri, üzerinden yapılan bir değişkenin kapsamını sınırlamaktır var. Aracılığıyla oluşturulan değişkenlerin varbir işlevle sınırlı bir kapsamı vardır, bu nedenle bu yapı (belirli bir kodun etrafındaki bir işlev sarmalayıcısıdır), değişken kapsamınızın bu işlevden dışarı sızmamasını sağlar.

Aşağıdaki örnekte, counthemen çağrılan işlevin dışında kullanılamayacak, yani kapsamı işlevin dışına countsızmayacaktır. Bir almalısınız ReferenceErrorzaten hemen çağrılan fonksiyonun dışında erişmeye çalışmalısınız.

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

ES6 Alternatif (Önerilen)

ES6'da artık letve aracılığıyla değişkenler oluşturabiliriz const. Her ikisi de blok kapsamlıdır ( varişlev kapsamının aksine ).

Bu nedenle, yukarıda bahsettiğim kullanım durumu için bu karmaşık IIFE yapısını kullanmak yerine, bir değişkenin kapsamının istediğiniz bloğun dışına çıkmadığından emin olmak için artık çok daha basit bir kod yazabilirsiniz.

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

Bu örnekte, kod bloğuyla sınırlı yapan , kıvırcık parantezlerle oluşturduğumuz değişkeni lettanımladık .countcount{...}

Ben buna "Kıvırcık Hapishane" diyorum.


10
Kıvırcık Hapishane ismini seviyorum . Belki yapışır :)
gion_13

15
(function () {
})();

Buna IIFE (Hemen Çağırılan İşlev İfadesi) denir. Ünlü JavaScript tasarım modellerinden biri, modern Modül modelinin kalbi ve ruhu. Adından da anlaşılacağı gibi, oluşturulduktan hemen sonra yürütülür. Bu model, yalıtılmış veya özel bir yürütme kapsamı oluşturur.

ECMAScript 6'dan önceki JavaScript sözcüksel kapsam belirleme kullandı, bu nedenle blok kapsam belirlemeyi simüle etmek için IIFE kullanıldı. (ECMAScript 6 ile ve letve constanahtar sözcüklerin tanıtılmasıyla blok kapsam belirleme mümkündür .) Sözcüksel kapsam belirleme sorununa referans

IIFE ile blok kapsam belirleme simülasyonu

Hayatta en kullanmanın performans yararı gibi yaygın olarak kullanılan genel nesneler geçmek yeteneği window, documentkapsamı arama azaltarak bir bağımsız değişken olarak, vb. (JavaScript'in yerel kapsamdaki mülkleri aradığını ve zinciri global kapsama kadar yükselttiğini unutmayın). Bu nedenle, global nesnelere yerel kapsamda erişmek aşağıdaki gibi arama süresini azaltır.

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

IIFE'deki ikinci parantezin anlaşılması için özgeçmiş sağladığınız için teşekkür ederiz. Ayrıca küresel değişkenin tanım zamanını tanımlayarak arama süresi faydasını açıklığa kavuşturmak için
Arsal

11

Hayır, bu yapı yalnızca adlandırma için bir kapsam oluşturur. Parçalara ayırırsanız, harici bir

(...)();

Bu bir işlev çağrısıdır. Parantez içinde:

function() {}

Bu anonim bir işlevdir. Yapı içinde var ile bildirilen her şey sadece aynı yapı içinde görünür olacak ve global isim alanını kirletmeyecektir.


11

Bu, Javascript'te hemen çağrılan bir işlev ifadesidir:

JS'de IIFE'yi anlamak için onu parçalayalım:

  1. İfade : Değer döndüren bir şey
    Örnek: Chrome konsolunda aşağıdakileri deneyin. Bunlar JS'deki ifadelerdir.
a = 10 
output = 10 
(1+3) 
output = 4
  1. İşlev İfadesi :
    Örnek:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

İşlev ifadesi nasıl çalışır:
- JS altyapısı ilk kez çalıştırıldığında (Yürütme Bağlamı - Aşama Oluştur), bu işlev (= üstündeki sağ tarafta) yürütülmez veya bellekte depolanmaz. Değişken 'selamlama', JS motoru tarafından 'tanımsız' değer olarak atanır.
- Yürütme sırasında (Yürütme Bağlamı - Yürütme aşaması), işlev nesnesi anında oluşturulur ( henüz yürütülmemiştir ), 'selamlama' değişkenine atanır ve 'selamlama (' somename ')' kullanılarak çağrılabilir.

3. Hemen Çağırılan İşlev İfadesi:

Misal:

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

console.log(greeting)  // Namaste Santosh. 

IIFE'nin çalışma şekli :
- İşlev bildiriminden hemen sonra '() işaretine dikkat edin. Her işlev nesnesinin kendisine eklenebilir bir 'CODE' özelliği vardır. Ve '()' diş telleri kullanarak onu arayabiliriz (veya çağırabiliriz).
- Yani burada, yürütme sırasında (Yürütme Bağlamı - Yürütme Aşaması), işlev nesnesi oluşturulur ve aynı anda yürütülür - Bu nedenle, şimdi, funtion nesnesine sahip olmak yerine selamlama değişkeni dönüş değerine (bir dize) sahiptir.

JS'de tipik IIFE kullanımı:

Aşağıdaki IIFE modeli oldukça yaygın olarak kullanılmaktadır.

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • burada iki şey yapıyoruz. a) İşlev ifademizi parantez () içine sarma. Bu, sözdizimi ayrıştırıcısına () içine yerleştirilen her şeyin bir ifade olduğunu (bu durumda işlev ifadesi) ve geçerli bir kod olduğunu söyler.
    b) Bu fonksiyonu aynı zamanda sonunda () kullanarak çağırıyoruz.

Böylece bu fonksiyon aynı anda oluşturulur ve yürütülür (IIFE).

IIFE için önemli kullanım alanı:

IIFE kodumuzu güvende tutar.
- Bir işlev olan IIFE'nin kendi yürütme içeriği vardır, yani içinde oluşturulan tüm değişkenler bu işlev için yereldir ve genel yürütme bağlamıyla paylaşılmaz.

Uygulamamda iife.js ile birlikte başka bir JS dosyası (test1.js) kullandığımı varsayalım (aşağıya bakın).

// 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'.

Bu nedenle IIFE , istemeden küresel nesnelerle çarpışmadığımız güvenli kod yazmamıza yardımcı olur .


IIFE içinde fonksiyonlar yaratırsak, bunlara diğer bazı js veya jsx dosyalarında, yani reaksiyon bileşeninde nasıl erişebiliriz.
taş

IIFE kullanmamamıza rağmen selamlama değişkeni küresel selamlama değişkeni ile çarpışmayacak. Peki oradaki avantaj nedir?
Willy David Jr

6

Bu kendi kendini çağıran anonim bir işlevdir .

Check out kendinden yürütmesini işlevinin W3Schools açıklama .

İşlev ifadeleri "kendi kendini çağıran" yapılabilir.

Kendini çağıran bir ifade çağrılmadan otomatik olarak çağrılır (başlatılır).

İfadeyi () izliyorsa işlev ifadeleri otomatik olarak yürütülür.

Bir işlev bildirimini kendiniz çağıramazsınız.


3
(function named(){console.log("Hello");}());<- kendi kendini yürüten adlı işlev
bryc

@bryc neden bir isme ihtiyaç duymayan bir fonksiyona isim veresin.
RicardoGonzales

2
@RicardoGonzales Özyineleme Sanırım
bryc

5

Bu kendi kendini çağıran anonim işlevdir. Tanımlanırken yürütülür. Yani bu işlev tanımlanır ve tanımdan hemen sonra kendini çağırır.

Sözdiziminin açıklaması şöyledir: İlk ()parantez içindeki işlev, adı olmayan bir işlevdir ve bir sonraki ();parantez ile tanımlandığı zamanda çağrıldığını anlayabilirsiniz. Ve bu ikinci ()parantez içinde, ilk parantez içindeki işlevde yakalanacak herhangi bir argümanı iletebilirsiniz . Bu örneğe bakın:

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

Burada, geçtiğiniz 'nesneye' işlev imzasında yakaladığınız için, işlev içinde 'obj' ile erişilebilir.


2
Bu sorunun zaten kabul edilmiş bir cevabı var ve cevabınız kabul edilen cevapta henüz ele alınmamış hiçbir şey eklemiyor. Bu nedenle, bu cevabı yazmaya kesinlikle gerek yoktu.
Aadit M Shah

3
Birden fazla cevap okumayı seviyorum, bazen birinin ya da diğerinin cümleleri bir fark yaratıyor.

Eklediğini düşündüm çünkü ikinci parantez setinin ne için olduğunu bana bildiriyor. En azından burada gördüğüm daha açıktı.
johnny

Benim favorilerim. Numune IIFE'nin her iki ucunda parametreler vardır ve ikisi arasındaki eşleme düzleştirilir.
Stephen W. Wright

4

Buradan başlayın:

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

Bir işleve koyun ve artık küresel değil - birincil hedefiniz.

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

İşlevi hemen arayın - oops:

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

Sözdizimi hatasını önlemek için parantezleri kullanın:

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

İşlev adını bırakabilirsiniz:

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

Bundan daha karmaşık olması gerekmez.


2
Sözdizimi hatası ok işlevlerinden bahsediyor. Anladığım kadarıyla, js'nin yeni bir özelliği ve birkaç yıl önce yoktu, ama IIFE yaptı. Yani, parantez muhtemelen başlangıçta bir sözdizimi hatasını önlemek için kullanıldı, ancak farklı mı?
JCarlosR

@JCarlos sorusuna cevap verebilir misiniz? IIFE'nin ok işlevinden önce çok geldiğine dikkat çektiği için, sarmanın neden gerekli olduğunu anlamaya yardımcı olacaktır.
Script47

@ Script47 Yorumdaki JCarlos'un sorusuna bir cevabım yok. Yeni bir soru formüle edebilir ve gönderebilirsiniz ve eminim bazı iyi yanıtlar alacaksınız.
Jim Flood

@JCarlos hata atar birini yürüttüğümde, aslında Uncaught SyntaxError: Unexpected token )ok işlevi herhangi bir söz almak yerine. Muhtemelen onunla ok işlevi hatası atarak bir keman paylaşabilir misiniz?
Script47

2

Kendi kendini yürüten anonim işlev. Oluşturulur oluşturulmaz yürütülür.

Bunun yararlı olduğu kısa ve kukla bir örnek:

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);

Her seferinde bir liste oluşturmak yerine, listeyi yalnızca bir kez (daha az ek yük) oluşturursunuz.


1
Yazıldığı gibi, aramanız her çağrıdaki listeyi yeniden oluşturur. Bundan kaçınmak için, (1) listeyi yapmanız ve (2) arama işlevini az önce yaptığınız listeye erişimi olan bir kapak olarak döndürmeniz gerekir. Bu, anonim kendini çağırma formunu kullanarak kolayca yapabilirsiniz. Bkz. Jsfiddle.net/BV4bT .
George

açıklayabilir misiniz ... daha az havai .. i dint anlamak bu kısmı
HIRA THAKUR

2
Genel gider gerekli olmayan herhangi bir iş anlamına gelir. Her işlev çağrısında bir dizi doldurmak gerekli değildir, bu nedenle örnekteki bir dizi kendi kendine yürütme tarafından doldurulur. sadece ilk kez anonim işlev. Ancak, kendi cevabımda bir hata yaptığım anlaşılıyor, uygun bir örnek için George'un yorumundaki bağlantıya bakın.
usoban

2

Kendi kendine çalışan işlevler genellikle bağlamı kapsüllemek ve ad çakışmalarını önlemek için kullanılır. (Function () {..}) () içinde tanımladığınız herhangi bir değişken global değildir.

Kod

var same_name = 1;

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

console.log(same_name);

bu çıktıyı üretir:

2
1

Bu sözdizimini kullanarak, JavaScript kodunuzun başka bir yerinde bildirilen genel değişkenlerle çarpışmaktan kaçınabilirsiniz.


1
Doğru, çıkış 2 ve sonra 1 olacaktı çünkü myVar önce çalıştırılacak
Dalibor

1
Açıklamanız işlev kapsamını açıklamada iyi sonuç verir, ancak neden hemen yürütüldüğünü açıklamakta yetersiz kalır. Bir değişkeni atamak kendi kendini yener ve bir kereden fazla çalıştırılabileceğini de düşünebilir. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Aynı sonucu alır.
domenicr

2

Buna IIFE - Hemen Çağırılan Fonksiyon İfadesi denir. İşte sözdizimi ve kullanımını gösteren bir örnek. Değişkenlerin kullanımını ötesine değil, sadece işleve kadar kapsamlamak için kullanılır.

(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 (Hemen çağrılan işlev ifadesi), komut dosyası yüklenir yüklenmez ve gider gitmez çalışan bir işlevdir.

İife.js adlı bir dosyada yazılı aşağıdaki işlevi düşünün

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

Yukarıdaki kod, iife.js'yi yükler yüklemez yürütülür ve ' Merhaba Stackoverflow! 'geliştirici araçları' konsolunda.

Ayrıntılı bir açıklama için bkz. Hemen Başlatılan İşlev İfadesi (IIFE)


1

Bir başka kullanım örneği de, bir önbellek nesnesinin genel olmadığı bir nottur:

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

Hemen çağrılan bir işlev ifadesi (IIFE) oluşturulduğu anda yürütülen bir işlevdir. Herhangi bir olay veya asenkron yürütme ile bağlantısı yoktur. Bir IIFE'yi aşağıda gösterildiği gibi tanımlayabilirsiniz:

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

İlk parantez işlevi () {...}, parantez içindeki kodu bir ifadeye dönüştürür. İkinci parantez çifti, ifadeden kaynaklanan işlevi çağırır.

Bir IIFEde kendi kendine çağırarak anonim fonksiyon olarak tanımlanabilir. En yaygın kullanımı, var üzerinden yapılan bir değişkenin kapsamını sınırlamak veya isim çarpışmalarını önlemek için bağlamı kapsüllemek.


0

Kendini uyandıran anonim işlevlerin kullanılmasının nedeni, çağrılması gereken kodu (işlevlere ve değişkenlere kapsam vermekle birlikte) "ayarladıkları" için asla başka bir kodla çağrılmamalarıdır.

Diğer bir deyişle, programın başlangıcında "sınıf yapan" programlara benzerler.Onlar başlatıldıktan sonra (otomatik olarak), kullanılabilen tek işlev anonim işlev tarafından döndürülen işlevlerdir. hidden 'işlevleri, herhangi bir durumla birlikte (kapsam oluşturma sırasında ayarlanan değişkenler) hala oradadır.

Çok havalı.


0

Aşağıdaki kod:

(function () {

})();

Bir adlandırılır hemen çağrılan işlevi, ifade (Hayatta).

Bir fonksiyon ifadesi olarak adlandırılır, çünkü ( yourcode )Javascript'teki operatör onu bir ifadeye zorlar. İşlev ifadesi ile işlev bildirimi arasındaki fark şudur:

// declaration:
function declaredFunction () {}

// expressions:

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

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

Bir ifade tek bir değere göre değerlendirilebilen bir kod grubudur . Yukarıdaki örnekteki ifadelerde bu değer tek bir işlev nesnesiydi .

Bir fonksiyon nesnesini değerlendiren bir ifadeye sahip olduktan sonra , fonksiyon nesnesini hemen operatörle çağırabiliriz() . Örneğin:

(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

Bu neden faydalı?

Büyük bir kod tabanı ile uğraşırken ve / veya çeşitli kütüphaneleri içe aktardığımızda çakışmaları adlandırma şansı artar. Kodumuzun bir IIFE içinde ilişkili olan (ve dolayısıyla aynı değişkenleri kullanan) belirli kısımlarını yazarken, tüm değişkenler ve fonksiyon adları IIFE'nin fonksiyon parantezlerine dahil edilir . Bu, ad çakışmaları olasılığını azaltır ve onları daha dikkatsiz olarak adlandırmanıza izin verir (örneğin, önek eklemeniz gerekmez).


0

ES6 sözdiziminde (hızlı bir örnek arayan bu sayfaya inmeye devam ederken kendim için gönderiyorum):

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

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

0

Bu işleve kendi kendini çağırma işlevi denir. Kendini çağıran (kendinden yürütme olarak da adlandırılır) işlevi, tanımından hemen sonra çağrılan (Çağrılan) adsız (anonim) bir işlevdir. Buradan daha fazlasını okuyun

Bu işlevlerin yaptığı, işlev tanımlandığında, işlevin hemen çağrılmasıdır, bu da zamandan ve fazladan kod satırından tasarruf sağlar (ayrı bir satırda çağırmaya kıyasla).

İşte bir örnek:

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



0

Bir işlev ifadesidir, Hemen Çağırılmış İşlev İfadesi (IIFE) anlamına gelir. IIFE, oluşturulduktan hemen sonra yürütülen bir işlevdir. Bu nedenle, çalıştırılmaya çağrılıncaya kadar beklemek zorunda olan fonksiyondan yola çıkarak IIFE hemen yürütülür. Örnek olarak IIFE'yi oluşturalım. Diyelim ki iki tamsayı argüman olarak alan ve toplamı döndüren bir add fonksiyonumuz var, add fonksiyonunu IIFE'ye dönüştürelim,

1. Adım: İşlevi tanımlayın

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

Adım 2: Tüm işlev bildirimini parantez içine alarak işlevi çağırın

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

Adım 3: İşlevi hemen faturalandırmak için 'ekle' metnini aramadan kaldırın.

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

Bir IFFE kullanmanın temel nedeni , işleviniz içindeki özel bir kapsamı korumaktır. Javascript kodunuzun içinde, herhangi bir genel değişkeni geçersiz kılmadığınızdan emin olmak istiyorsunuz. Bazen yanlışlıkla bir global değişkeni geçersiz kılan bir değişken tanımlayabilirsiniz. Örnek olarak deneyelim. iffe.html adında bir html dosyanız olduğunu ve gövde etiketinin içindeki kodların

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

Yukarıdaki kod herhangi bir soru olmadan yürütülür, şimdi yanlışlıkla veya kasıtlı olarak belge adlı bir değişkeni iptal ettiğinizi varsayalım.

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

Bir de endup edecek SyntaxError : yapılandırılamayan küresel mülkiyet belgesinin yeniden bildirilmiş.

Ama eğer isteğiniz değişken bir isim belgesini köreltmekse IFFE'yi kullanarak yapabilirsiniz.

<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>

Çıktı:

resim açıklamasını buraya girin

Başka bir örnekle deneyelim, körük gibi bir hesap makinesi nesnemiz olduğunu varsayalım.

<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>

Peki bir cazibe gibi çalışıyor, ya yanlışlıkla hesap makinesi nesnesinin değerini yeniden atarsak.

<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>

evet bir TypeError ile bitireceksiniz: calculator.mul iffe.html bir işlev değildir

Ancak IFFE'nin yardımıyla başka bir değişken adı hesaplayıcısı oluşturabileceğimiz ve kullanabileceğimiz özel bir kapsam oluşturabiliriz;

<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>

Çıktı: resim açıklamasını buraya girin


-1

2 küme parantezinin biraz kafa karıştırıcı olduğunu düşünüyorum ama googles örneğinde başka bir kullanım gördüm, benzer bir şey kullandılar, umarım bu daha iyi anlamanıza yardımcı olacaktır:

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

eğer öyleyse windows.apptanımlı değil, o zaman window.app = {}hemen yürütülür, bu nedenle window.appile atanır {}sonuç her iki yüzden, durum değerlendirmesi sırasında appve window.appşimdi haline {}konsol çıkışı yani,:

Object {}
Object {}

-1

Genellikle, bir işlevi programa yazdıktan hemen sonra çağırmayız. Son derece basit bir ifadeyle, bir işlevi oluşturulduktan hemen sonra çağırdığınızda, buna süslü bir isim olan IIFE denir.


-1

Normalde, JavaScript kodunun uygulamada genel kapsamı vardır. İçinde global değişken ilan ettiğimizde, aynı yinelenen değişkeni, gelişimin başka bir alanında başka bir amaçla kullanma şansı vardır. Bu çoğaltma nedeniyle bazı hatalar olabilir. Bu nedenle, hemen işlev ifadesini çağırarak bu global değişkenlerden kaçınabiliriz, bu ifade kendi kendini yürüten ifadedir. Kodumuzu bu IIFE içinde yaptığımızda genel değişken yerel kapsam ve yerel değişken gibi olacak anlatım.

IIFE oluşturmanın iki yolu

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

VEYA

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

Yukarıdaki kod snippet'inde “ var app ” artık yerel bir değişkendir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.