LowCoder,
Материал:
- "проблема":
http://javascript.ru/ecma/part12#a-12.4
- решение:
http://javascript.ru/ecma/part11#a-11.1.6
Скажу кратко (подробно, нужно потратить больше времени, текста и уже нужно иметь определённую теоретическую базу), чтобы не путать.
Функции деляться на:
- "Функция-Объявление" (FunctionDeclaration, FD);
- "Функция-Выражение" (FunctionExpression, FE).
Разницу сейчас тоже не буду описывать, т.к. это не важно в данном вопросе.
Так вот, исходя из
п.12.4:
Цитата:
|
ИнструкцияВыражение не может начаться с открывающей фигурной скобки, т.к. тогда оно было бы неотличимо от Блока. Также ИнструкцияВыражение не может начинаться с ключевого слова function, т.к. тогда оно было бы неотличимо от ОбъявленияФункции
|
Т.е.
function a() {}();
Ошибка, т.к. неотличимо от "Функция-Объявление", которую нельзя вызвать сразу.
Соответственно, нужно переделать выражение так, чтобы оно стало "Функция-Выражение". Самый простой способ -
оператор группировки.
(function a() {})();
Все ок, т.к. теперь это FE.
Но основная суть данных конструкций, это создание "private"-переменных, которые будут доступны в наших функциях/объектах (а их мы вернём наружу и сможем использовать), но не будут загрязнять глобальное пространство. На простом синтетическом примере:
var a = (function () { var b = 10; return b; })();
Создаём FE, и тут же её вызываем. Переменная "а" теперь 10, но переменная "b" не существует после вызова функции.
Конструкию (function () { _наш_код_ })(); можно назвать
инициализирующим пространством нашего объекта/библиотеки и т.д. Это пространство позволит вернуть наружу минимальный интерфейс, но (повторюсь) внутри себя иметь множество дополнительных, вспомогательных объектов, которые будут не видны снаружи:
var a = (function () {
// "private"
var b = 10;
function c() {
return b + 10;
}
// интерфейс наружу
return {
test: c,
q: b,
z: function () {
return c() + 10;
}
};
})();
// "a" инициализирован
// надеюсь, понятно, что "а" - есть возвращённый объект, но не функция!
// функция (FE) использовалась нами лишь для создания
// "нашего пространства" и для возвращения этого объекта
alert(a.test()); // 20
alert(a.q); // 10
alert(a.z()); // 30
Однако, ни "b", ни "c" не доступны посредством "а" напрямую.