Самовызывающиеся функции в Javascript

| Суббота, 26 июля, 2014

Метки Javascript


Javascript кажется немного странным языком, который иногда делает странные вещи. Такие мысли могут возникнуть, если не следить за лучшими практиками и не быть знакомым со стандартом ECMA. Странности встречаются и в синтаксисе и семантике. Одна из таких вещей – это самовызывающиеся функции (self-invoking functions).

Cинтаксис:

(function () {
    // код функции 
 }());

Главной идеей является то, что анонимная функция вызывается сразу после своего объявления. Преимущество от использования самовызывающихся функций вы получите, если нужно выполнить код один раз и сохранить его резульататы во "внешней среде" (без объявления глобальных переменных).

Например, для небольшой веб-страницы можно написать обработчики событий для элементов на странице. Самовызывающиеся функции подходящее средство для такой ситуации.

Что фактически будет происходить?

Как видно из примера выше, мы определили анонимную функцию и нет никаких глобальных переменных. И даже нет локальных, за исключением тех, что мы будем использовать внутри функции. Мы не храним нигде ссылку на эту функцию. Нигде не храним возвращаемое значение. Так только функция инициализирована, она тут же вызывается.

Это может быть удобным вариантом инициализации, например, мы инициализируем и прикрепляем функции обработчиков событий один раз, после объявления функции вызываем ее, и теряем с ней связь.

Существует несколько видов синтаксиса этих функций. Хотя разница очень мала, но приведем примеры. Дуглас Крокфорд, один из разработчиков Javascript, считает правильной такую запись самовызывающейся функции:

(function () {
    //body
}());

А вот другой вариант, который Крокфорд, называет "собачьи яйца" (dog balls).

(function () {
    //body
})();

Некоторые считают, что второй вариант более удобен.

Такой вариант тоже работает, но почему-то нигде не встречается:

function () {
    //body
}();

В самовызывающуюся функцию можно передавать параметры. Это общая практика передачи ссылок на глобальные объекты:

(function (w, d, $) {
   //body
}(window, document, jQuery));

Не рекомендуется передавать слишком много аргументов (больше трех-четырех), потому что если функция становится больше в размерах, то нужно постоянно скроллить, чтобы вспомнить нужный параметр, а если их много то это приходится делать довольно часто. Если вы легко запоминаете аргументы, то нужно быть благосклонным к тем, кто будет читать код после вас.

И самое интересное, ради чего и замыслился весь этот пост, самовызывающуюся функцию можно использовать в модульном паттерне (module pattern). Мы сохраняем ссылку на возвращаемое значение, а именно на API модуля:

var module = (function () {
    //private
    return {
    //public
    }
}());

Статей про модульный паттерн существует очень много, очень удобная штука для тех, кто писал классы в C#, С++ т.п.

Итак, самовызывающиеся функции – это функции, вызывающие сами себя, использовать их или нет зависит от вас, но понимать их надо. Иногда их еще называют как немедленно исполняемые функции (Immediately Invoked Functions).