erniesto77
@erniesto77
oop, mvc, rb, py, php, js

Что значит оборачивание функции в скобки (function() { ... })?

Для вызова самой себя разумеется скажете вы, что то в этом духе
(function() { ... })()
но тогда пустые скобки () должны пытаться вызвать undefined как функцию. Но такого не происходит и вообще пустые скобки это ситаксическая ошибка

иными словами почему наличие функции в скобках как то интерпретируется а отсутствие функции в скобках вообще ошибка
  • Вопрос задан
  • 8568 просмотров
Решения вопроса 1
copist
@copist
Мидл, хочешь стать синьором? http://copi.st/ExhE
Короткий ответ
(function() { ... })()
Это определение анонимной функции без параметров и непосредственный вызов её, так же, без параметров

Длинный ответ
Зачем оборачивать значение в круглые скобки?

Оборачивание функции в скобки, так же как и оборачивание константы в скобки - это просто способ показать интерпретатору, что это значение внутри скобок может быть использовано как возвращаемое значение.
var var_a = 5
(var_a) /* или */ (5) // не является ошибкой, возвращает значение переменной или выражения
function func_b() { }
(func_b) /* или */ (function func_b() { }) // не является ошибкой, возвращает ссылку на функцию
var var_c = { key: "val" }
(var_c) /* или */ ({ key: "val" }) // не является ошибкой, возвращает объект
var var_d = [ "one", "two" ]
(var_d) /* или */ ([ "one", "two" ]) // не является ошибкой, возвращает массив


Ну а раз (func_b) - это ссылка на функцию func_b, то значит её можно сразу же вызвать.
A если (var_c) - это объект, то значит можно сразу же использовать его
Аналогично (var_d) - это массив, то значит можно сразу же использовать его

(func_b)() или (function func_b() { })() вызвать функцию
(var_c).key или ({ "key": "val" }).key использовать объект
(var_d)[0] или ([ "one", "two" ])[0] использовать массив

Синтаксической ошибкой было бы использование функции, массива, объекта без скобок ( )
function func_b() { }() ошибка "Unexpected token )"

Хотя нет ошибки, по крайней мере в Google Chrome
{ key: "val" }["key"]
["one", "two"][0]

Для чего вообще придумали самовызывающиеся функции?
Для того, чтобы изолировать переменные и функции, чтобы они не попадали в глобальную область видимости.

Сравни
var a = "test"
alert(a)

по завершении этого блока переменная a болтается в глобальной области видимости

и
(function(){
    var a = "test"
})()

alert(a) // недоступно, потому что она была локальной переменной внутри анонимной функции


Почему скобки ( ) пустые?
В данном случае у функции function() { ... }нет формальных параметров, значит и вызывать можно без параметров.

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

(function (w, d, $) {
   // некоторым нравится сокращать код путём использования коротких имён переменных
   w['fizz'] = "buzz" // вот так можно принудительно зарегистрировать
                       // глобальную переменную fizz
   $('body').css({background: 'red'}) // вот так можно работать с jQuery через привычную $
                       // даже если библиотека была загружена в режиме noСonflict
}(window, document, jQuery))


Некоторым не нравится длинный вариант проверки на undefined и они специально предусматривают лишний параметр, который не инициализируют

(function (message1, message2, empty) {
    // это и есть проверка на undefined
    if (message1 === empty)
        alert('message1 is undefined')
    else
        alert('message1 = ' + message1)

    if (message2 === empty)
        alert('message2 is undefined')
    else
        alert('message2 = ' + message2)
})("test") // вызвана только с одним параметром, значит второй по имени message2
//  будет пустой, а третий empty специально ввели в качестве образца
//  данных с типом "undefined", для служебного использования

Зачем функция анонимная?
Аналогично - чтобы не регистрировать её имя в глобальной области видимости, если она нужна один раз.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы