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

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

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

за это:

//Bunch of code...

16 ответов


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

например:

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

alert(foo); 

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


упрощенно. Так что очень нормальный вид, его почти утешает:

var userName = "Sean";

console.log(name());

function name() {
  return userName;
}

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

подождать... что?

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

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

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

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

поэтому нам нужно как-то расширить наш код.

единственный способ расширить код в javascript-это обернуть его в функцию:

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

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

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

у нас есть функция в функции... что странно смотреть at, но совершенно законно.

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

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

function main() {
  // We are now in our own sound-proofed room and the 
  // character-converter libarary's 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's name() function can exist at the 
  // same time as ours. 

  var userName = "Sean";

  console.log(name());

  function name() {
    return userName;
  }
}

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

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

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

((){})();

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

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

Итак, давайте посмотрим на наш код снова, с некоторым самоисполнимости синтаксис:

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

    console.log(name());

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

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

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

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

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


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

Я большой поклонник :) он:

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

чрезвычайно – (почему вы должны сказать, что это хорошо?)

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

больше здесь.


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


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

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

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

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

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


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

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

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


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

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


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

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...


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


я прочитал все ответы,чего-то очень важного здесь не хватает, я поцелую. Есть 2 основные причины, почему мне нужны самоисполняющиеся анонимные функции, или лучше сказать"немедленно вызванное выражение функции (IIFE)":

  1. лучшее управление пространством имен (избегая загрязнения пространства имен -> модуль JS)
  2. замыкания (имитация частных членов класса, как известно из ООП)

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

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

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

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

давайте попробуем некоторые эксперименты:

я могу сделать 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

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


самозваная функция в javascript:

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


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

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


(function(){ var foo = { name: 'bob' }; console.log(foo.name); // bob })(); console.log(foo.name); // Reference error

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

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

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


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

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

глобальная переменная имеет глобальную область действия; она определяется везде в коде 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.


похоже, что на этот вопрос был дан ответ, но я все равно опубликую свой ввод.

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

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

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

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

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


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