Показать сообщение отдельно
  #10 (permalink)  
Старый 20.06.2009, 13:35
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

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" не доступны посредством "а" напрямую.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 20.06.2009 в 14:21.
Ответить с цитированием