Как работает конструктор (function() {})() и почему люди его используют?

(function() {})() и его jQuery-cousin (function($) {})(jQuery) всплывает все время в коде Javascript.

Как работают эти конструкции и какие проблемы они решают?

Примеры, оцененные

Ответ 1

С ростом популярности фреймворков JavaScript знак $ использовался во многих случаях. Итак, чтобы облегчить возможные столкновения, вы можете использовать эти конструкции:

(function ($){
  // Your code using $ here.
})(jQuery);

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

Ответ 2

Это метод, используемый для ограничения области переменных; это единственный способ предотвратить заражение переменных глобальным пространством имен.

var bar = 1; // bar is now part of the global namespace
alert(bar);

(function () {
   var foo = 1; // foo has function scope
   alert(foo); 
   // code to be executed goes here
})();

Ответ 3

1) Он определяет анонимную функцию и выполняет ее сразу.

2) Обычно это делается для того, чтобы не загрязнять глобальное пространство имен нежелательным кодом.

3) Вам нужно выставить из него некоторые методы, все, что объявлено внутри, будет "private", например:

MyLib = (function(){
    // other private stuff here
    return {
        init: function(){
        }
    };

})();

Или, альтернативно:

MyLib = {};
(function({
    MyLib.foo = function(){
    }
}));

Дело в том, что вы можете использовать его, но результат остается тем же.

Ответ 4

Это просто анонимная функция, вызываемая немедленно. Сначала вы можете создать функцию, а затем вызвать ее, и вы получите тот же эффект:

(function(){ ... })();

работает как:

temp = function(){ ... };
temp();

Вы также можете сделать то же самое с именованной функцией:

function temp() { ... }
temp();

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

Вы можете сделать то же самое в два этапа, и вы можете сделать это с любыми параметрами, которые вам нравятся:

temp = function(answer){ ... };
temp(42);

Проблема, что это решает, заключается в том, что она создает закрытие для кода в функции. Вы можете объявлять переменные в нем, не загрязняя глобальное пространство имен, тем самым уменьшая риск конфликтов при использовании одного script вместе с другим.

В конкретном случае для jQuery вы используете его в режиме совместимости, где он не объявляет имя $как псевдоним для jQuery. Отправляя объект jQuery в закрытие и именовав параметр $, вы все равно можете использовать тот же синтаксис, что и без режима совместимости.

Ответ 5

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

Переменные привязаны к уровню функций в javascript. Это отличается от того, к чему вы могли бы привыкнуть на языке С# или Java, где переменные привязаны к блоку. Это означает, что если вы объявите переменную внутри цикла или оператора if, она будет доступна для всей функции.

Если вам когда-либо понадобится явно использовать переменную внутри функции, вы можете использовать анонимную функцию для этого. Фактически вы можете создать анонимную функцию, а затем выполнить ее сразу, а все переменные внутри будут обладать анонимной функцией:

(function() {
  var myProperty = "hello world";
  alert(myProperty);
})();
alert(typeof(myProperty)); // undefined

Ответ 6

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

;(function($){
   ... your jQuery code here...
})(jQuery);

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

Ответ 7

Другое использование этой конструкции - "захватить" значения локальных переменных, которые будут использоваться в закрытии. Например:

for (var i = 0; i < 3; i++) {
    $("#button"+i).click(function() {
        alert(i);
    });
}

В приведенном выше коде будут отображаться все три кнопки "3". С другой стороны:

for (var i = 0; i < 3; i++) {
    (function(i) {
        $("#button"+i).click(function() {
            alert(i);
        });
    })(i);
}

Это заставит три кнопки вывести "0", "1" и "2", как ожидалось.

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

Ответ 8

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

var i = 0;
alert("The magic number is " + i);

(function() {
   var i = 99;
   alert("The magic number inside the closure is " + i);
})();

alert("The magic number is still " + i);

Это создаст три всплывающих окна, демонстрируя, что i в закрытии не изменяет ранее существовавшуюся переменную с тем же именем:

  • Магическое число 0
  • Магическое число внутри закрытия 99
  • Магическое число все равно 0

Ответ 9

Они часто используются в плагинах jQuery. Как объяснено в jQuery Plugins Authoring Guide, все переменные, объявленные внутри { }, являются частными и не видны снаружи, что позволяет улучшить инкапсуляцию.

Ответ 10

Как говорили другие, оба они определяют анонимные функции, которые вызывают немедленно. Обычно я объявляю свои объявления классов JavaScript в этой структуре, чтобы создать статическую закрытую область для класса. Затем я могу разместить в этой области постоянные данные, статические методы, обработчики событий или что-то еще, и это будет видимо только для экземпляров класса:

// Declare a namespace object.
window.MyLibrary = {};

// Wrap class declaration to create a private static scope.
(function() {
  var incrementingID = 0;

  function somePrivateStaticMethod() {
    // ...
  }

  // Declare the MyObject class under the MyLibrary namespace.
  MyLibrary.MyObject = function() {
    this.id = incrementingID++;
  };

  // ...MyObject prototype declaration goes here, etc...
  MyLibrary.MyObject.prototype = {
    memberMethod: function() {
      // Do some stuff
      // Maybe call a static private method!
      somePrivateStaticMethod();
    }
  };
})();

В этом примере класс MyObject присваивается пространству имен MyLibrary, поэтому он доступен. incrementingID и somePrivateStaticMethod() не доступны напрямую вне области анонимной функции.

Ответ 11

Это в основном пространство имен вашего кода JavaScript.

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

() в конце означает self invoke. Вы также можете добавить туда аргумент, который станет аргументом вашей анонимной функции. Я часто делаю это с jQuery, и вы можете понять, почему...

(function($) {

    // Now I can use $, but it won't affect any other library like Prototype
})(jQuery);

Эван Trimboli описывает остальное в своем ответе .

Ответ 12

Это самозапускающаяся функция. Вид вроде стенографии для написания

function DoSomeStuff($)
{
}

DoSomeStuff(jQuery);

Ответ 13

Что делает вышеприведенный код, это создать анонимную функцию в строке 1, а затем вызвать ее в строке 3 с помощью 0 аргументов. Это эффективно инкапсулирует все функции и переменные, определенные в этой библиотеке, потому что все функции будут доступны только внутри этой анонимной функции.

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

Чтобы выяснить, как вызывается функция, рассмотрим простой пример:

Если у вас есть эта единственная строка включенного Javascript, она будет автоматически вызываться без явного вызова:

alert('hello');

Итак, возьмите эту идею и примените ее к этому примеру:

(function() {
    alert('hello')
    //anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked

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

Ответ 14

Потому что ответы на код good уже приняты:) Я предложу посмотреть видео John Resig видео 1, видео 2 (изобретатель jQuery и мастер на JavaScript).

Некоторые действительно хорошие идеи и ответы, представленные в видео.

Именно это я и делал в тот момент, когда я увидел ваш вопрос.

Ответ 15

function(){ // some code here }

- способ определить анонимную функцию в javascript. Они могут дать вам возможность выполнять функцию в контексте другой функции (где у вас может не быть этой способности иначе).