что это такое
В JavaScript каждая функция, когда она вызывается, создает новый контекст выполнения. Поскольку переменные и функции, определенные в функциях, являются единственными переменными, к которым доступны внутренне, а не внешне, при вызове функции, контекст, предоставленный функцией, обеспечивает очень простой способ создания частных переменных.
function makeCounter () {var i = 0; return function () {console.log (++ i); }; } // Помните: `counter` и` counter2` имеют свои собственные переменные `i`var counter = makecounter (); counter (); // 1counter (); // 2var counter2 = makecounter (); counter2 (); // 1counter2 (); // 2i; // referenceerror: i не определяется (это только exist in makececececececececec oxecOn);Во многих случаях вам может не понадобиться такая функция, как макияж, чтобы вернуть несколько накопленных значений, и вы можете позвонить ее только один раз, чтобы получить одно значение, и в некоторых других случаях вам даже не нужно знать возвращаемое значение явно.
Его ядро
Теперь, независимо от того, что вы определяете функцию, подобную функции foo () {} или var foo = function () {}, при вызове вам нужно добавить пару скобок после нее, например, foo ().
// Функция, определенная ниже, может быть вызвана путем добавления пару кронштейнов после имени функции, например, `foo ()`, // Потому что Foo - это просто эталонная переменная var foo = function () {/ * code */} `относительно выражения функции` function () {/ * code */} `var foo = funct скобки после этого? function () { / * code * /} (); // синтаксисерсор: неожиданный токен (Как видите, здесь поймана ошибка. Когда скобки появляются за функцией, чтобы вызвать функцию, независимо от того, сталкиваетесь ли вы с таким ключевым словом функции в глобальной среде или в локальной среде, по умолчанию он будет рассматривать его как объявление функции, а не как выражение функции. Если вы явно не говорите скобкам, что это выражение, оно будет рассматривать его как функцию без имени и бросить ошибку, поскольку объявление функции требует имени.
Вопрос 1: Могу ли я подумать о вопросе здесь? Можем ли мы также вызвать функцию var foo = function () {console.log (1)} () непосредственно таким, и ответ в порядке.
Вопрос 2: Точно так же мы также можем подумать о вопросе. Если после этого объявление о функции называется непосредственно с скобками, что происходит? Пожалуйста, смотрите ответ ниже.
Функция, скобки, ошибка
Интересно, что если вы указали имя для функции и поставите за ней пару скобок, та же ошибка будет выброшена, но на этот раз это по другой причине. Когда скобки размещаются после выражения функции, это указывает на то, что это называется функция, а скобки размещаются после объявления, это означает, что они полностью отделены от предыдущего объявления функции. В настоящее время скобки - это просто простое представление о скобках (скобки, используемые для управления приоритетом работы).
// однако, объявление функции является синтаксически недействительным, оно все еще является объявлением, и следующие скобки являются недействительными, потому что скобки должны включать функцию выражения foo () {/ * code */} (); // Синтаксисерр: неожиданный токен // Вы ставите выражение в скобки, не бросая ошибку ... но функция не выполняется, но функция не выполняется, но функция не выполняется, но функция не выполняется, но функция не выполняется, но функция не выполняется, но функция не выполняется, но функция не выполняется, но функция foo () {/ * code */} (1) // он эквивалентен следующему, объявление функции следует за выражением, которое вообще не имеет отношения: function foo () {/ * code */} (1);Немедленно выполнить выражения функции (iife)
К счастью, легко исправить грамматические ошибки. Наиболее популярный и наиболее принятый метод заключается в том, чтобы обернуть объявления функций в скобках, чтобы сообщить парсеру выразить выражение функции, потому что в JavaScript скобки не могут содержать объявления. Из -за этого, когда скобки сталкиваются с ключевым словом функции, чтобы обернуть функцию, он знает, чтобы анализировать его как выражение функции вместо объявления функции. Обратите внимание на понимание того, что скобки здесь отличаются от приведенных выше скобок, когда они сталкиваются с функциями, то есть, то есть
Когда скобки появляются в конце анонимной функции и захотят вызвать функцию, это по умолчанию будет рассматривать функцию как объявление функции.
При завершении функции в скобках она будет анализировать функцию как выражение по умолчанию, а не объявлять функцию.
// Оба шаблона могут использоваться для немедленного вызова выражения функции, используя выполнение функции для создания частных переменных (function () {/ * code */} ()); // Крокфорд рекомендует это, выражение в скобках представляет функцию сразу (функция () {/ * Code */}) (// но это работает, а также выражение, потому что параметрирует, потому что выражение, потому что выражение, потому что выражение, потому что выражение, потому что Функция. Операторы должны устроиться на дисковоци зрения // между выражениями функций и объявлениями функций, они могут быть // опущены, когда парсер уже ожидает выражения (но, пожалуйста, см. // «Важная примечание» ниже) .var i = function () {return 10;} (); true && function () {/*code*/} (); 0, function () {} (); Возможно, вы можете хранить байты, взяв унарального оператора перед вашей функцией! function () {/ * code */} (); ~ function () {/ * code */} (); - function () {/ * code */} ();+function () {/ * code */} (); // Вот еще один вариант, от @kuvos - я не уверен в эффективности // IMPLICATIONS, если есть ли есть использование, но это клавиша @kuvos - // //, но оно работает, но оно работает. http://twitter.com/kuvos/status/18209252090847232new function () {/ * code */} new Function () {/ * code */} () // нуждаются в парировании, только при передаче аргументовВажные заметки о скобках
В некоторых случаях нет необходимости окружать выражение функции, когда дополнительные неоднозначные кронштейны находятся вокруг выражения функции (поскольку кронштейны уже выражаются как выражение), но это все еще хорошая идея, когда кронштейны используются для вызова выражения функции.
Такие кронштейны показывают, что выражение функции будет вызвано немедленно и что переменная будет хранить результат функции, а не саму функцию. Когда это очень длинное выражение функции, это экономит время, чем люди, читающие ваш код, без необходимости прокрутки в нижней части страницы, чтобы увидеть, вызвана ли функция.
Как правило, когда вы пишете четкий и четкий код, необходимо предотвратить бросок JavaScript, а также необходимо предотвратить отсутствие других разработчиков ошибки в Wtferror!
Сохранить статус закрытия
Точно так же, как когда функция называется их именем, параметры передаются, и когда выражение функции называется немедленно, параметры передаются. Непосредственное выражение функции может использоваться для блокировки значений и эффективного сохранения состояния в настоящее время, поскольку любая функция, определенная в функции, может использовать параметры и переменные, передаваемые внешней функцией (эта связь называется закрытием).
// это может не сработать, как вы думаете, потому что ценность «я никогда не заблокирована». // Наоборот, когда каждая ссылка нажимается (цикл хорошо выполнен), поэтому общее количество всех элементов появится, // потому что это истинное значение «Я» в настоящее время. var elems = document.getElementsbytagname ('a'); for (var i = 0; i <elems.length; i ++) {elems [i] .addeventListener ('click', function (e) {e.preventdefault (); Alert ('I Link #'+ I), FALSE); заблокирован в `lockedinindex`. // Когда цикл выполняется, хотя числовое значение значения «я» - это сумма всех элементов, каждый раз, когда называется выражение функции, значение «lockedInindex» в iife - это значение, передаваемое ему «i», поэтому, когда ссылка нажимается, правильное значение появляется. var elems = document.getElementsbytagname ('a'); for (var i = 0; i <elems.length; i ++) {(function (lockedInindex) {elems [i] .AdDeventListener ('click', function (e) {e.preventDefault (); alert ('im im link #'+lockedinidex); }) (i);} // Вы также можете использовать IIFE, как следующее, просто используя скобки, чтобы включить функцию обработки клика, и не включать всю `addEventListener`. // Независимо от того, каким образом оба примера могут быть заблокированы с помощью iife, но я обнаружил, что предыдущий пример является более читаемым varems = document.getelementsbytagname ('a'); for (var i = 0; i <elems.length; i ++) {elems [i] .addeventLister ('click', (function (function (functedIndex) {return) {efer) {eep) {eef eef eef efaultex; 'I Link #' + lockedinindex); }Помните, что в этих двух последних примерах LockedInindex может получить доступ к I без каких -либо проблем, но использование другого идентификатора идентификатора в качестве параметра функции может облегчить интерпретацию концепции.
Одним из наиболее важных преимуществ выполнения функции немедленно является то, что даже если она не названа или анонимно, выражение функции может быть вызвано немедленно без использования идентификатора, и закрытие может использоваться без загрязнения текущей переменной.
Какова проблема с самооценкой анонимной функции («самостоятельная анонимная функция»)?
Вы видели, как это упоминалось несколько раз, но это все еще не так ясно объяснено, я бы предложил изменить термин на «сразу внедренное выражение функции», или, если вам нравится аббревиатура.
Что сразу же наводится экспрессией функции? Это делает выражение функции сразу. Это как выражение функции, которое заставляет вас позвонить.
Я думаю, что члены сообщества JavaScript должны иметь возможность принять термины, немедленно включенное выражение функции и IIFE в своих статьях или заявлениях, потому что я чувствую, что легче понять концепцию, и термин «самостоятельная анонимная функция» на самом деле недостаточно точна.
// Ниже приведена функция самостоятельного выполнения, которая рекурсивно называет свою собственную функцию foo () {foo ();}; // Это самостоятельная анонимная функция. Поскольку он не имеет идентификатора, он должен использовать свойство `arguments.callee`, чтобы назвать его сами по себе var foo = function () {arguments.callee ();}; // Это можно считать самостоятельной анонимной функцией, но это также возможно, если вы замените ее на` foo ', чтобы вызовать var foot = {fooo (); (); Анонимная функция, как это, даже если она не является самооценкой, потому что она не называется себя. Затем это было только что вызвано немедленно. (function () {/*code*/} ()); // Добавление идентификатора в выражение функции (то есть создание именованной функции) будет очень полезно для нашей отладки. После названия функция больше не будет анонимной. (function foo () {/ * code */} ()); // iifes также может быть выполнен сама по себе, хотя, возможно, это не самый полезный шаблон (function () {arguments.callee ();} ()) (function foo () {foo ();} () // Последнее, что следует обратить внимание: это будет вызовать ошибку в Blackberry 5, потому что //////// Последнее. Потрясающе, а? (Function foo () {foo ();} ());Надеемся, что приведенный выше пример даст вам более четкое представление о термине самостоятельного выполнения, которое несколько вводит в заблуждение, поскольку он не выполняет свою собственную функцию, хотя функция выполнена. Точно так же нет необходимости указывать на анонимные функции, потому что немедленно вызываемая экспрессия функции может быть либо именованной функцией, либо анонимной функцией.
Последний: модульный режим
Когда я вызову выражение функции, если я напоминаю себе о шаблоне модуля хотя бы один раз, я, скорее всего, проигнорирую его. Если у вас нет шаблона модуля в JavaScript, он очень похож на мой пример ниже, но возвращаемое значение использует объект вместо функции.
var counter = (function () {var i = 0; return {get: function () {return i;}, set: function (val) {i = val;}, urment: function () {return ++ i;}}} ()); counter.get (); // 0 counter.set (3); counter.increment (); // 4 counter.increment (); // 5 conuter.i; // не определен (`i 'не является свойством возвращаемого объекта) i; // referenceerr: i не определяется (он существует только внутри закрытия)Метод режима модуля не только довольно мощный, но и прост. С очень небольшим кодом вы можете эффективно использовать именование, связанное с методами и атрибутами. В объекте организация всех кодов модулей сводит к минимуму загрязнение глобальных переменных и создает использование переменных.