Skip to content

Latest commit

 

History

History
134 lines (97 loc) · 4.62 KB

immediately-invoked-function-expression-iife.md

File metadata and controls

134 lines (97 loc) · 4.62 KB

Immediately Invoked Function Expression (IIFE)

Natychmiastowo-wywoływane wyrażenie funkcyjne

Natychmiastowo-wywoływane wyrażenie funkcyjne, jest często stosowane w języku JavaScript, ponieważ w języku tym bloki nie tworzą nowego zakresu zmiennych, tak jak to ma miejsce w przypadku języka **Java **czy C. Stosuje się je także aby odizolować część kodu od reszty programu. Jej konstrukcja polega na zamknięciu całej funkcji w nawiasy (może być to funkcja anonimowa) i natychmiastowym jej wywołaniu. Zapis taki tworzy domknięcie.

(function () {
    console.log('SolwIT');
}());

https://codepen.io/Bigismall/pen/qjNOMw

Powyższy skrypt spowoduje wypisanie w konsoli napisu "SolwIT". Skoro wspomniano już o domknięciu i zakresie funkcyjnym, prześledźmy kolejny skrypt.

var solwIT = 'SolwIT';

(function () {
    var intel = 'Intel';
    console.log(solwIT);
    console.log(intel);
}());

try {
    console.log(solwIT);
    console.log(intel);
} catch (e) {
    console.warn(e.message);
}

https://codepen.io/Bigismall/pen/QgEjZM

w wyniku powyższego otrzymamy:

SolwIT
Intel
SolwIT
intel is not defined

Info: W EcmaScript 6 zamiast tworzenia funkcji IIFE dla powyższego przykładu, można wykorzystać operator let oraz nawiasy { }.

Parametry funkcji natychmiastowych

Do funkcji natychmiastowych można także przekazać argumenty, co przedstawia poniższy przykład.

(function (message, a, b) {
    console.log(message, a + b);                //SolwIT JS Basic. And the sum is:  5
}("SolwIT JS Basic. And the sum is: ", 2, 3));

https://codepen.io/Bigismall/pen/xrOwyB

Bardzo często jako argument funkcji podaje się obiekt globalny, by był on dostępny wewnątrz funkcji, bez potrzeby korzystania z np. nazwy window. Rozwiązanie to czyni kod bardziej przenośnym, bo działa prawidłowo w środowiskach innych niż przeglądarka internetowa.

(function (global) {
    if (global.hasOwnProperty('alert')) {
        console.log('Uruchamiasz mnie w przeglądarce');
    } else {
        console.log('Uruchamiasz mnie poza przeglądarką');
    }
}(this));

https://codepen.io/Bigismall/pen/NgrGEg

W przykładzie powyżej przekazano this, będącym referencją do obiektu globalnego. W zależności od posiadania przez obiekt globalny właściwości alert, wyświetlony zostanie odpowiedni komunikat.

Wartości zwracane przez funkcje natychmiastowe

Podobnie jak każda inna funkcja, także funkcja natychmiastowa może zwrócić wartość, a ta może zostać przypisana do zmiennej.

var sumResult = (function (a, b) {
    return a + b;
}(2, 5));

console.log(sumResult);     //7

https://codepen.io/Bigismall/pen/KqMdJZ

Może też zwrócić: funkcję (co przyda nam się w dalszych rozdziałach), obiekt lub sama być użyta w konstrukcji obiektu

var sum = (function () {
    return function (a, b) {
        return a + b;
    }
}());

console.log(sum);            // [Function]
console.log(sum(2, 4));      // 6

https://codepen.io/Bigismall/pen/GEqpeq

Zalety i zastosowanie

Wzorzec funkcji natychmiastowej stosowany jest powszechnie. Pozwala na wykonanie określonych zadań bez zaśmiecania przestrzeni globalnej zmiennymi tymczasowymi. Wszystkie zdefiniowane zmienne są lokalne względem funkcji natychmiastowej i nie wyjdą poza nią, chyba że programista zadecyduje inaczej.

Wzorzec pozwala umieścić poszczególne zestawy funkcjonalności w szczelnych modułach. Jako przykład, szkielet definicji modułu UMD .

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['exports', 'b'], function (exports, b) {
            factory((root.commonJsStrictGlobal = exports), b);
        });
    } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
        // CommonJS
        factory(exports, require('b'));
    } else {
        // Browser globals
        factory((root.commonJsStrictGlobal = {}), root.b);
    }
}(this, function (exports, b) {
    //use b in some fashion.

    // attach properties to the exports object to define
    // the exported module properties.
    exports.action = function () {};
}));