Выбрать главу

function mymodule() {

  // Здесь находится реализация модуля.

  // Любые переменные, используемые модулем, превратятся в локальные

  // переменные этой функции и не будут засорять глобальное пространство имен.

}

mymodule(); // Но не забудьте вызвать функцию!

Данный программный код объявляет единственную глобальную переменную: имя функции «mymodule». Если даже единственное имя это слишком много, можно определить и вызвать анонимную функцию в одном выражении:

(function() { // функция mymodule переписана как неименованное выражение

  // Здесь находится реализация модуля.

}()); // конец литерала функции и ее вызов.

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

Практическое применение приема создания пространства имен демонстрируется в примере 8.3. Здесь определяется анонимная функция, возвращающая функцию extend(), подобную той, что была представлена в примере 6.2. Анонимная функция проверяет наличие хорошо известной ошибки в Internet Explorer и возвращает исправленную версию функции, если это необходимо. Помимо этого, анонимная функция играет роль пространства имен, скрывающего массив с именами свойств.

Пример 8.3. Функция extend(), исправленная, если это необходимо

// Определяет функцию extend, которая копирует свойства второго и последующих аргументов

// в первый аргумент. Здесь реализован обход ошибки в IE: во многих версиях IE цикл for/in

// не перечисляет перечислимые свойства объекта о, если одноименное свойство

// его прототипа является неперечислимым. Это означает, что такие свойства,

// как toString, обрабатываются некорректно, если явно не проверять их.

var extend = (function() { // Присвоить значение, возвращаемое этой функцией

  // Сначала проверить наличие ошибки, прежде чем исправлять ее.

  for(var р in {toString:null}) {

    // Если мы оказались здесь, значит, цикл for/in работает корректно

    // и можно вернуть простую версию функции extend()

    return function extend(o) {

      for(var і = 1; і < arguments.length; i++) {

        var source = arguments[i];

        for(var prop in source) o[prop] = source[prop];

      }

      return o;

    };

  }

  // Если мы оказались здесь, следовательно, цикл for/in не перечислил

  // свойство toString тестового объекта. Поэтому необходимо вернуть версию extend(),

  // которая явно проверяет неперечислимость свойств прототипа Object.prototype.

  // Список свойств, которые необходимо проверить