16 ответов:
все о области видимости переменной. Переменные, объявленные в самоисполняющейся функции, по умолчанию доступны только для кода внутри самоисполняющейся функции. Это позволяет писать код, не заботясь о том, как переменные называются в других блоках кода 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'.
Итак, кто-то хороший человек написал всеобъемлющий конвертер символов, который я могу включить в свой сайт... Я включаю его.
одна проблема: в нем есть функция под названием "Имя", такая же, как и моя функция.
это то, что называется столкновение. У нас есть две функции, объявленные в том же scope С тем же именем. Мы хотим этого избежать.
поэтому нам нужно как-то расширить наш код.
единственный способ охватить код в 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; } }что может решить нашу проблему. Все теперь заключено и может быть доступно только из наших открывающих и закрывающих скобок.
у нас есть функция в функции... что странно смотреть на, но совершенно законно.
только одна проблема. Наш код не работает. Наша переменная имени пользователя никогда не отражается в консоли!
мы можем решить эту проблему, добавив вызов нашей функции после нашего существующего блока кода...
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 (также известный как авто-вызов) - это когда функция исполняет сразу после его определение. Это основной шаблон и служит основой для многих другие шаблоны JavaScript развитие.
Я большой поклонник :) он:
- он держит код до минимума
- он обеспечивает отделение поведения от представления
- он обеспечивает закрытие, которое предотвращает именование конфликты
чрезвычайно – (почему вы должны сказать, что это хорошо?)
- речь идет об определении и выполнении функции сразу.
- вы можете иметь эту самоисполняющуюся функцию, возвращающую значение и передающую функцию в качестве параметра другой функции.
- это хорошо для инкапсуляции.
- это также хорошо для блока области.
- Да, вы можете вложить все свои .JS файлы в самоисполняющейся функции и может предотвратить глобальный загрязнение пространства имен. ;)
больше здесь.
Я не могу поверить, что ни один из ответов не упоминает подразумеваемые глобалы.
The
(function(){})()конструкция не защищает от подразумеваемых глобалов, что для меня является большей проблемой, см. http://yuiblog.com/blog/2006/06/01/global-domination/В основном функциональный блок гарантирует, что все зависимые "глобальные vars", которые вы определили, ограничены вашей программой, он не защищает вас от определения неявных глобалов. JSHint или как может дать рекомендации о том, как защититься от такого поведения.
более лаконичные
var App = {}синтаксис обеспечивает аналогичный уровень защиты, и может быть завернут в функциональный блок, когда на "публичных" страницах. (см. Эмбер.js или SproutCore для реальных примеров библиотек, которые используют эту конструкцию)насколько
privateсвойства идут, они немного переоценены, если вы не создаете публичную структуру или библиотеку, но если вам нужно их реализации, Дуглас Крокфорд есть несколько хороших идей.
есть ли параметр и "куча кода" возвращает функцию?
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 основные причины, почему мне нужны самоисполняющиеся анонимные функции, или лучше сказать"сразу-вызывается функция выражения (жизнь)":
- лучшее управление пространством имен (избегая загрязнения пространства имен - > JS модуль)
- замыкания (имитация частных членов класса, как известно из ООП)
первый был очень хорошо объяснил. Для второго, пожалуйста, изучите следующий пример:
var MyClosureObject = (function (){ var MyName = 'Michael Jackson RIP'; return { getMyName: function () { return MyName;}, setMyName: function (name) { MyName = name} } }());внимание 1: мы не назначаем функцию
MyClosureObject, далее результат вызова этой функции. Будьте в курсе()в последней строке.внимание 2: что вы дополнительно должны знать о функциях в Javascript, так это то, что внутренние функции получают доступ к параметрам и переменным 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 RIPEdit: в приведенном выше примере
MyClosureObjectпредназначен для использования безnewпрефикс, поэтому по соглашению он не должен быть капитализированный.
самопроизвольная функция в javascript:
самопроизвольное выражение вызывается (запускается) автоматически, без вызова. Самопроизвольное выражение вызывается сразу после его создания. Это в основном используется для предотвращения конфликтов имен, а также для достижения инкапсуляции. Переменные или объявленные объекты недоступны вне этой функции. Для того, чтобы избежать проблем минимизации(именем.мин) всегда используйте функцию собственной личности исполненную.
поскольку функции в Javascript являются первоклассным объектом, определяя его таким образом, он эффективно определяет "класс" так же, как C++ или C#.
эта функция может определять локальные переменные и иметь функции внутри нее. Внутренние функции (эффективно методы экземпляра) будут иметь доступ к локальным переменным (эффективно переменные экземпляра), но они будут изолированы от остальной части скрипта.
(function(){ var foo = { name: 'bob' }; console.log(foo.name); // bob })(); console.log(foo.name); // Reference errorна самом деле, указанная выше функция будет рассматриваться как выражение функции без имени.
основная цель обертывания функции с закрытыми и открытыми скобками заключается в том, чтобы избежать загрязнения глобального пространства.
переменные и функции внутри выражения функции стали частными (т. е. они не будут доступны вне функции.
самоисполняющиеся функции используются для управления областью действия переменной.
область действия переменной-это область программы, в которой он определен.
глобальная переменная имеет глобальную область действия; она определяется везде в вашем коде JavaScript и может быть доступна из любого места в скрипте, даже в ваших функциях. С другой стороны, переменные, объявленные в функции, определяются только в теле функции. Они являются локальными переменными, имеют локальные область и может быть доступна только в пределах этой функции. Параметры функции также считаются локальными переменными и определяются только в теле функции.
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> }кодирование вообще имеет много неясных способов делать много одних и тех же вещей, заставляя вас задаться вопросом: "Зачем беспокоиться?"Но появляются новые ситуации, когда вы больше не можете полагаться только на основные/основные принципы.
Comments