Какова цель функции самоисполнения в javascript?

В javascript, когда вы хотите использовать это:

(function(){
    //Bunch of code...
})();

над этим:

//Bunch of code...
+391
26 февр. '09 в 20:53
источник поделиться
17 ответов

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

Например:

(function(){ 
    var foo = 3; 
    alert(foo); 
})(); 

alert(foo); 

Сначала появится предупреждение "3", а затем выдается ошибка при следующем предупреждении, поскольку foo не определен.

+371
26 февр. '09 в 20:57
источник

Simplistic. Очень нормальный взгляд, его почти утешительный:

var userName = "Sean";

console.log(name());

function name() {
  return userName;
}

Однако. Что, если я включу на мою страницу действительно удобную библиотеку javascript, которая переводит продвинутые символы в их представления на базовом уровне?

Подождите... что?

Я имею в виду. Если кто-то набирает персонажа с каким-то акцентом на него (например, французский или испанский персонаж), но мне нужны только "английские" персонажи? A-z в моей программе? Ну... испанские "n ~" и французские "e/" персонажи (я использовал для этого два символа, но вы, вероятно, можете сделать умственный прыжок в персонаже, который представляет акценты), эти символы могут быть переведены в базовые символы 'n' и 'e'.

Итак, кто-то хороший человек написал всеобъемлющий конвертер символов, который я могу включить в свой сайт... Я включаю его.

Одна проблема: в ней есть функция, называемая "имя", как и моя функция.

Это то, что называется столкновением. У нас есть две функции, объявленные в одной области с тем же именем. Мы хотим избежать этого.

Итак, нам нужно каким-то образом охватить наш код.

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

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

Это может решить нашу проблему. Теперь все закрыто и доступно только из наших открывающих и закрывающих брекетов.

У нас есть функция в функции... которая выглядит странно, но вполне законна.

Только одна проблема. Наш код не работает. Наша переменная userName никогда не повторяется в консоли!

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

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

main();

Или раньше!

main();

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

Второе беспокойство: каковы шансы, что имя "main" еще не было использовано?... так очень, очень тонко.

Нам нужно больше очков. И каким-то образом автоматически выполнить нашу функцию main().

Теперь мы приходим к функциям автоматического выполнения (или самоисполняющимся, автономным, независимо).

(() {})();

Синтаксис неудобен как грех. Однако он работает.

Когда вы завершаете определение функции в круглых скобках и включаете список параметров (другой набор или круглые скобки!), он действует как вызов функции.

Итак, давайте снова посмотрим на наш код с помощью некоторого самостоятельного синтаксиса:

(function main() {
  var userName = "Sean";

    console.log(name());

    function name() {
      return userName;
    }
  }
)();

Итак, в большинстве учебных пособий, которые вы читаете, теперь вы будете бомбардировать термином "анонимное самоисполнение" или что-то подобное.

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

Когда что-то пойдет не так (и оно будет), вы будете проверять обратную линию в своем браузере. Всегда легче сузить проблемы с кодом, когда записи в трассировке стека имеют имена!

Очень надолго, и я надеюсь, что это поможет!

+78
09 мая '15 в 8:13
источник

Self-invocation (также известный как авто-вызов), когда функция немедленно выполняет свои определение. Это основной шаблон и служит основой для многих другие шаблоны JavaScript развитие.

Я отличный поклонник:), потому что:

  • Он сохраняет минимальный код
  • Он обеспечивает разделение поведения с представлением
  • Он обеспечивает закрытие, которое предотвращает конфликты имен

Необычно - (Почему вы должны сказать, что это хорошо?)

  • Об определении и выполнении функции все сразу.
  • Возможно, эта функция самоисполнения вернет значение и передаст функцию как параметр в другую функцию.
  • Это хорошо для инкапсуляции.
  • Он также хорош для просмотра области.
  • Да, вы можете вложить все ваши .js файлы в функцию самоисполнения и предотвратить глобальное загрязнение пространства имен.;)

Подробнее здесь.

+33
19 мая '10 в 15:39
источник

Пространство имен. Области JavaScript являются функциональными.

+19
26 февр. '09 в 20:56
источник

Я не могу поверить, что ни один из ответов не упоминает подразумеваемые глобальные переменные.

Конструкция (function(){})() не защищает от подразумеваемых глобальных переменных, что для меня больше беспокоит, см. http://yuiblog.com/blog/2006/06/01/global-domination/

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

Более сжатый синтаксис var App = {} обеспечивает аналогичный уровень защиты и может быть включен в функциональный блок, когда он находится на "общедоступных" страницах. (см. Ember.js или SproutCore для реального мира примеры библиотек, которые используют эту конструкцию)

Что касается свойств private, они скорее переоцениваются, если вы не создаете общедоступную структуру или библиотеку, но если вам нужно их реализовать, Дуглас Крокфорд имеет несколько хороших идей.

+12
13 апр. '12 в 5:42
источник

Есть ли параметр, а "Букет кода" возвращает функцию?

var a = function(x) { return function() { document.write(x); } }(something);

Закрытие. Значение something используется функцией, назначенной a. something может иметь какое-то переменное значение (для цикла) и каждый раз, когда a имеет новую функцию.

+7
26 февр. '09 в 21:03
источник

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

Конечно, на половине реализаций JS там они все равно будут.

+6
26 февр. '09 в 20:57
источник

Это потрясающая статья, объясняющая все это и почему это хорошая практика программирования: http://markdalgleish.com/2011/03/self-executing-anonymous-functions/

+6
03 дек. '17 в 2:26

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

for( var i = 0; i < 10; i++ ) {
  setTimeout(function(){
    console.log(i)
  })
}

Выход: 10, 10, 10, 10, 10...

for( var i = 0; i < 10; i++ ) {
  (function(num){
    setTimeout(function(){
      console.log(num)
    })
  })(i)
}

Выход: 0, 1, 2, 3, 4...

+5
19 нояб. '15 в 20:55
источник

Я прочитал все ответы, здесь что-то очень важное отсутствует, я ПОКУПАЮ. Есть две основные причины, почему мне нужны самозаверяющие анонимные функции, или лучше сказано " Выражение выраженной функции (IIFE)":

  • Лучшее управление пространством имен (исключение загрязнения пространства имен → JS-модуль)
  • Закрытие (моделирование членов частного класса, как известно из ООП)

Первое объяснено очень хорошо. Для второго, пожалуйста, изучите следующий пример:

var MyClosureObject = (function (){
  var MyName = 'Michael Jackson RIP';
  return {
    getMyName: function () { return MyName;},
    setMyName: function (name) { MyName = name}
  }
}());

Внимание 1: Мы не назначаем функцию MyClosureObject, еще больше результат вызова этой функции. Помните () в последней строке.

Внимание 2: Что вам дополнительно нужно знать о функциях в Javascript, так это то, что внутренние функции получают доступ к параметрам и переменным функций, они определены внутри.

Попробуем несколько экспериментов:

Я могу получить MyName с помощью getMyName, и он работает:

 console.log(MyClosureObject.getMyName()); 
 // Michael Jackson RIP

Следующий простой подход не сработает:

console.log(MyClosureObject.MyName); 
// undefined

Но я могу установить другое имя и получить ожидаемый результат:

MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName()); 
// George Michael RIP

Изменить: В приведенном выше примере MyClosureObject предназначен для использования без префикса new, поэтому по соглашению он не должен быть заглавным.

+4
05 дек. '17 в 12:26
источник

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

+3
26 февр. '09 в 20:58
источник

Функция self invoked в javascript:

Самозапускаемое выражение автоматически запускается (запускается) без вызова. Самозапускающееся выражение вызывается сразу после его создания. Это в основном используется для предотвращения именования конфликтов, а также для обеспечения инкапсуляции. Переменные или объявленные объекты недоступны вне этой функции. Для избежания проблем минимизации (filename.min) всегда используйте функцию самозапуска.

+2
20 окт. '15 в 13:02
источник

Так как функции в Javascript являются первоклассным объектом, определяя его таким образом, он эффективно определяет "класс", очень похожий на С++ или С#.

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

+1
26 февр. '09 в 20:57
источник

Функция самоисполнения используется для управления областью переменной.

Область действия переменной - это область вашей программы, в которой она определена.

Глобальная переменная имеет глобальный масштаб; он определяется везде в вашем JavaScript-коде и может быть доступен из любого места внутри скрипта даже в ваших функциях. С другой стороны, переменные, объявленные внутри функции, определяются только внутри тела функции. Они являются локальными переменными, имеют локальную область действия и могут быть доступны только внутри этой функции. Параметры функции также считаются локальными переменными и определяются только внутри тела функции.

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

var globalvar = "globalvar"; // this var can be accessed anywhere within the script

function scope() {
    alert(globalvar);
    localvar = "localvar" //can only be accessed within the function scope
}

scope(); 

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

+1
24 апр. '18 в 10:14
источник

Похоже, на этот вопрос ответил все готово, но я все равно отправлю свой ввод.

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

var myObject = {
    childObject: new function(){
        // bunch of code
    },
    objVar1: <value>,
    objVar2: <value>
}

Функция позволяет мне использовать дополнительный код для определения атрибутов и свойств childObjects для более чистого кода, например, для установки обычно используемых переменных или выполнения математических уравнений; Ой! или проверка ошибок. а не ограничивается синтаксисом создания вложенных объектов...

object: {
    childObject: {
        childObject: {<value>, <value>, <value>}
    }, 
    objVar1: <value>,
    objVar2: <value>
}

У кодирования вообще есть много неясных способов делать много одинаковых вещей, заставляя вас задаться вопросом: "Зачем беспокоиться"? Но новые ситуации продолжают появляться там, где вы больше не можете полагаться только на основных/основных директоров.

0
18 дек. '16 в 3:26
источник
(function(){
    var foo = {
        name: 'bob'
    };
    console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error

На самом деле, вышеуказанная функция будет рассматриваться как выражение функции без имени.

Основная цель обертывания функции с закрытыми и открытыми скобками - избежать загрязнения глобального пространства.

Переменные и функции внутри выражения функции стали частными (то есть) они не будут доступны вне функции.

0
31 мар. '17 в 10:14
источник

IIRC позволяет создавать частные свойства и методы.

-2
26 февр. '09 в 20:57
источник

Посмотрите другие вопросы по меткам или Задайте вопрос