Сконфигурировано скобкой JavaScript после выражения функции [duplicate]

Я знаю, что это действительно поздно, но выставлять его в любом случае на всякий случай, если это помогает другим. Вот функция, с которой я столкнулся, которая, похоже, хорошо разбирается в различиях между месяцами между двумя датами. Это, по общему признанию, намного бесполезнее, чем у мистера Коудера, но дает более точные результаты, пройдя через объект даты. Это в AS3, но вы должны просто убрать сильную типизацию, и у вас будет JS. Не стесняйтесь, чтобы он выглядел лучше всех!

    function countMonths ( startDate:Date, endDate:Date ):int
    {
        var stepDate:Date = new Date;
        stepDate.time = startDate.time;
        var monthCount:int;

        while( stepDate.time <= endDate.time ) { 
            stepDate.month += 1;
            monthCount += 1;
        }           

        if ( stepDate != endDate ) { 
            monthCount -= 1;
        }

        return monthCount;
    }
606
задан Taryn 22 March 2017 в 17:23
поделиться

20 ответов

Это короткое выражение Immediately Invoked Function / или IIFE . Он выполняется сразу после его создания.

Он не имеет никакого отношения к любому обработчику событий для любых событий (например, document.onload). Рассмотрим часть в первой паре круглых скобок: (function(){})(); .... это регулярное объявление функции. Затем посмотрите на последнюю пару (function(){})();, это обычно добавляется к выражению для вызова функции; в этом случае наше предыдущее выражение.

Этот шаблон часто используется при попытке избежать загрязнения глобального пространства имен, поскольку все переменные, используемые внутри IIFE (как и в любом другом нормальном функция) не видны за пределами ее объема. Вот почему, может быть, вы путаете эту конструкцию с обработчиком событий для window.onload, потому что это часто используется как это:

(function(){
    // all your code here
    var foo = function() {};
    window.onload = foo;
    // ...
})();
// foo is unreachable here (it’s undefined)

Исправление, предложенное Guffa :

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

676
ответ дан joeljpa 15 August 2018 в 16:29
поделиться
  • 1
    Коррекция: функция выполняется сразу после ее создания, а не после ее анализа. Весь блок сценария анализируется до того, как будет выполнен любой его код. Кроме того, код разбора автоматически не означает, что он выполнен, если, например, IIFE находится внутри функции, то он не будет выполняться до тех пор, пока функция не будет вызвана. – Guffa 27 September 2013 в 02:02
  • 2
    В ES6 вышеупомянутый IIFE можно переписать с помощью функции стрелки ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ), например. ((foo) => foo)('foo value'). – Gajus 18 December 2014 в 14:20
  • 3
    @Guffa ваш комментарий обсуждается здесь: meta.stackoverflow.com/q/314911/1927206 – Bill Woodger 19 January 2016 в 12:23
  • 4
    @jlei, как я вижу, жизненный цикл программы js включает в себя следующие этапы: синтаксический анализ, создание / компиляция, выполнение. Хотя фактическая реализация (и именование :)) может отличаться от браузера к браузеру, мы можем определить эти этапы в нашем коде, наблюдая за ошибками синтаксического анализа, сбоями и ошибками времени выполнения. Я лично не нашел много ресурсов на этом, потому что это слишком низкий уровень, и это не то, что программист может контролировать. Вы можете найти какое-то объяснение в этом сообщении SO: stackoverflow.com/a/34562772/491075 – gion_13 29 March 2016 в 05:45
  • 5
    JavaScript является самым странным синтаксическим победителем. – Hos Mercury 19 August 2016 в 16:24

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

(function() {
     // all your code here
     // ...
})();

Первая пара функций круглых скобок () {...} преобразует код в круглые скобки в выражение. вторая пара круглых скобок вызывает функцию, полученную из выражения.

А IIFE также может быть описана как самозапускающая анонимная функция. Его наиболее распространенное использование заключается в ограничении объема переменной, созданной с помощью var или инкапсуляции контекста, чтобы избежать конфликтов имен.

1
ответ дан abdulbarik 15 August 2018 в 16:29
поделиться

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

(...)();

. Это вызов функции. Внутри круглой скобки у вас есть:

function() {}

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

11
ответ дан Aldo Stracquadanio 15 August 2018 в 16:29
поделиться

IIFE (Немедленно вызывается выражение функции) - это функция, которая выполняется, как только скрипт загружается и уходит.

Рассмотрим приведенную ниже функцию в файле с именем iife.js

(function(){
       console.log("Hello Stackoverflow!");
   })();

. Этот код, указанный выше, будет выполнен, как только вы загрузите iife.js и напечатаете ' Hello Stackoverflow! "на консоли разработчика.

Подробное объяснение см. в Выражение с немедленной вызывной функцией (IIFE)

2
ответ дан clearlight 15 August 2018 в 16:29
поделиться

Это анонимная функция , которая является самоисключением . Обычно известный как Immediatly вызываемое выражение функции (IIFE).

1
ответ дан Community 15 August 2018 в 16:29
поделиться

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

Это как если бы вы назначили ее переменной и использовали ее сразу после, только без переменной:

var f = function () {
};
f();

В jQuery есть аналогичная конструкция, о которой вы могли бы подумать:

$(function(){
});

Это краткая форма привязки события ready:

$(document).ready(function(){
});
91
ответ дан Guffa 15 August 2018 в 16:29
поделиться
  • 1
    Последние два не являются IIFE, поскольку они вызывается, когда DOM готов, а не немедленно – svvac 22 May 2014 в 12:48
  • 2
    @swordofpain: Да, это правильно, они не IIFE. – Guffa 22 May 2014 в 18:04
  • 3
    @swordofpain с учетом второго фрагмента; будет ли какое-либо значение в add () до конца функции, превратив его в IIFE? – timebandit 25 July 2015 в 13:53
  • 4
    Нужна ли точка с запятой в конце? – FrenkyB 31 March 2017 в 12:09
  • 5
    @FrenkyB Не нужно, нет, но рекомендуется (точки с запятой часто на самом деле не нужны в Javascript, но это хорошая практика). Каждый из них - это утверждения, которые включают анонимные функции, а не объявления функций. – Ledivin 20 June 2017 в 17:41

Это выражение вызывается с немедленным вызовом в Javascript:

Чтобы понять IIFE в JS, давайте сломаем его:

  1. Выражение: что-то, возвращающее значение Пример: Попробуйте следовать в хром-консоли.
  2. Функция Expression: Пример:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');
< / blockquote>

Как работает выражение функции: - Когда JS-движок запускается в первый раз (Execution Context - Create Phase), эта функция (с правой стороны = выше) не запускается или не сохраняется в памяти. Переменной «greet» присваивается значение «undefined» двигателем JS. - Во время выполнения (Execution Context - Execute phase) объект funtion создается «на лету» (еще не выполнен), получает назначение переменной «greet» и может быть вызван с помощью «greet (« somename »)».

3. Сразу вызывается выражение Funtion:

Пример:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

Как работает IIFE: - Обратите внимание на «()» сразу после объявления функции. Каждый объект funtion имеет прикрепленное к нему свойство «CODE», которое может быть вызвано. И мы можем вызвать его (или вызвать) с помощью скобок (). - Таким образом, здесь, во время выполнения (Контекст выполнения - Выполнение фазы), объект функции создается и выполняется одновременно. Так что теперь вместо переменной funtion вместо переменной funtion есть возвращаемое значение (строка)

Типичная Usecase IIFE в JS:

В качестве примера используется обычная схема IIFE.

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • мы здесь делаем две вещи. a) Обертывание выражения функции внутри фигурных скобок (). Это означает, что синтаксический синтаксический анализатор все, что помещается внутри (), является выражением (выражение функции в этом случае) и является допустимым кодом. б) Мы вызываем эту функцию в то же время, используя () в конце ее.

Таким образом, эта функция создается и выполняется одновременно (IIFE).

Важная утилита для IIFE:

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

Предположим, что у меня есть еще один JS-файл (test1.js), используемый в моем приложении вместе с iife.js (см. ниже).

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

Итак, IIFE помогает нам писать безопасный код, где мы не сталкиваемся с глобальными объектами непреднамеренно.

6
ответ дан Hina Khuman 15 August 2018 в 16:29
поделиться
  • 1
    Если мы создадим функции внутри IIFE, как мы можем получить к ним доступ в каком-то другом файле js или jsx, то есть в компоненте реакции. – stone rock 12 June 2018 в 08:13
  • 2
    – Willy David Jr 4 September 2018 в 03:27

Я думаю, что два набора скобок делают это немного запутанным, но я видел другое использование в примере с Google, они использовали что-то похожее, я надеюсь, что это поможет вам лучше понять:

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

, так что если windows.app не определен, тогда window.app = {} немедленно выполняется, поэтому window.app назначается с помощью {} во время оценки условия, поэтому результат app и window.app теперь становятся {}, поэтому консоль выход:

Object {}
Object {}
0
ответ дан James Lin 15 August 2018 в 16:29
поделиться

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

0
ответ дан KawaiKx 15 August 2018 в 16:29
поделиться

Это говорит о том, что выполняйте немедленно.

, так что если я делаю:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

Fiddle: http://jsfiddle.net/maniator/LqvpQ/


Второй пример:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18
26
ответ дан Neal 15 August 2018 в 16:29
поделиться
  • 1
    Я не понимаю, что это доказывает, что он сам призывает? – Exitos 22 November 2011 в 16:22
  • 2
    @Exitos, потому что он возвращает эту функцию. Я приведу второй пример. – Neal 22 November 2011 в 16:23

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

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

Очень круто.

6
ответ дан Peter Mortensen 15 August 2018 в 16:29
поделиться
  • 1
    Этот вопрос уже имеет принятый ответ, и ваш ответ не добавляет ничего, что еще не было охвачено принятым ответом. Следовательно, совершенно не нужно было писать этот ответ. – Aadit M Shah 15 March 2015 в 08:33
  • 2
    Правильно, выход будет равен 2, а затем 1, потому что myVar будет запущен первым – Dalibor 23 March 2015 в 09:11
  • 3
    Мне нравится читать несколько ответов, иногда формулировка того или другого имеет значение. – user 20 May 2015 в 15:36
  • 4
    Ваше объяснение хорошо объясняет объем функций, но не объясняет, почему оно выполняется немедленно. Присвоение переменной переменной самоопределяется и может также предполагать, что ее можно выполнить несколько раз. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Имеет тот же результат. – domenicr 20 April 2016 в 15:55
  • 5
    Я подумал, что это добавлено, потому что это дало мне знать, для чего был второй набор круглых скобок. По крайней мере, здесь было яснее, что я видел. – johnny 23 November 2016 в 19:46
  • 6
    Мои любимые. Оба конца образца IIFE имеют параметры, а отображение между ними сделано равным. – Stephen W. Wright 7 March 2018 в 04:31

Обычно код javascrypt имеет глобальную область действия приложения. Когда мы объявляем глобальную переменную в нем, есть шанс использовать ту же повторяющуюся переменную в какой-то другой области разработки для какой-либо другой цели. Из-за этого дублирования может произойти некоторая ошибка. Таким образом, мы можем избежать этих глобальных переменных, используя сразу вызывающее выражение функции, это выражение является самоисполняющимся выражением. Когда мы делаем наш код внутри этого выражения IIFE, глобальная переменная будет похожа на локальную область и локальную переменную.

Two мы можем создать IIFE

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

ИЛИ

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

В приведенном выше фрагменте кода « var app » теперь является локальной переменной.

0
ответ дан Rinoy Ashokan 15 August 2018 в 16:29
поделиться

Начать здесь:

var b = 'bee';
console.log(b);  // global

Поместить его в функцию и больше не глобально - ваша основная цель.

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

Вызовите функцию немедленно - oops:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

Используйте круглые скобки, чтобы избежать синтаксической ошибки:

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

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

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

Это не должно быть более сложным, чем это.

3
ответ дан Shashank Gaurav 15 August 2018 в 16:29
поделиться
  • 1
    Синтаксическая ошибка говорит о функциях стрелок. Как я понимаю, это новая функция js, и она не существовала несколько лет назад, но IIFE. Итак, скобки, вероятно, использовались изначально, чтобы избежать синтаксической ошибки, но другая? – JCarlos 1 July 2017 в 14:08
  • 2
    Не могли бы вы ответить на вопрос @JCarlos? Поскольку он совершенно справедливо указывает на то, что IIFE много сделал перед функцией стрелки, это поможет понять, почему требуется упаковка. – Script47 22 August 2017 в 11:42
  • 3
    @ Script47 У меня нет ответа на вопрос JCarlos в комментарии. Вы могли бы сформулировать новый вопрос и опубликовать его, и я уверен, что вы получите хорошие ответы. – Jim Flood 22 August 2017 в 19:36
  • 4
    @JCarlos, когда я выполняю ту, которая вызывает ошибку, я фактически получаю Uncaught SyntaxError: Unexpected token ), а не любое упоминание о функции стрелки. Не могли бы вы поделиться с ним скрипкой, которая бросает ошибку функции стрелки? – Script47 22 August 2017 в 19:49

Это анонимная функция самозапускания.

Проверьте объяснение W3Schools функции самозапускания .

Выражения функции может быть сделано «самозапускающимся».

Самозависающее выражение вызывается автоматически (автоматически) без вызова.

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

Вы не можете самостоятельно вызывать объявление функции.

8
ответ дан SiggyF 15 August 2018 в 16:29
поделиться
  • 1
    (function named(){console.log("Hello");}()); & lt; - self-executing с именем – bryc 17 August 2015 в 08:04
  • 2
    @bryc, почему вы назовете функцию, которая не нуждается в имени. – RicardoGonzales 26 June 2017 в 03:58
  • 3
    @RicardoGonzales Рекурсия Я думаю – bryc 27 June 2017 в 14:38

Объявляет анонимную функцию, затем называет ее:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);
31
ответ дан solendil 15 August 2018 в 16:29
поделиться
  • 1
    Я думаю, что «аргументы» являются внешними переменными, на которые ссылаются как "arg" для использования в локальном контексте внутри функции? – Dalibor 25 March 2015 в 09:35
  • 2
    @Dalibor arguments - special ; я думаю, что ответчик просто щелкнул там, где имена – cat 1 March 2016 в 03:36
(function () {
})();

Это называется IIFE (Expression Exited Function Expression). Один из знаменитых шаблонов дизайна javascript, и это сердце и душа современного модульного модуля. Как видно из названия, он выполняется сразу после его создания. Этот шаблон создает изолированную или личную область выполнения.

JavaScript до ECMAScript 6 с использованием лексического охвата, IIFE используется для имитации охвата блока. (С блочным охватом ECMAScript 6 возможно с введением ключевого слова let и const.) Ссылка на вопрос с лексическим охватом

Имитация блочного охвата с помощью IIFE

Преимущество производительности использования IIFE заключается в возможности передавать общеупотребительные глобальные объекты, такие как окно, документ и т. д. В качестве аргумента можно уменьшить просмотр области. (Помните, что Javascript ищет свойство в локальной области и вверх цепочки до глобального масштаба). Таким образом, доступ к глобальным объектам в локальной области, сокращает время поиска, как показано ниже.

(function (globalObj) {
//Access the globalObj
})(window);
18
ответ дан stuart_mad 15 August 2018 в 16:29
поделиться
  • 1
    Мне нравится имя Curly Jail . Может быть, он будет придерживаться :) – gion_13 13 February 2017 в 11:53
  • 2
    Благодарим вас за предоставленную информацию, чтобы понять вторую скобку в IIFE. Кроме того, для выяснения выгоды времени поиска глобальной переменной путем определения их в определении – Arsal 19 April 2017 в 08:16

Функциональное выражение с немедленным вызовом (IIFE) немедленно вызывает функцию. Это просто означает, что функция выполняется сразу после завершения определения.

Три более распространенных формулировки:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

Если особых значений для возвращаемого значения нет, тогда мы можем написать:

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

В качестве альтернативы это может быть:

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

Вы даже можете написать:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
43
ответ дан The Red Pea 15 August 2018 в 16:29
поделиться
  • 1
    last one 31.new 'является недопустимым синтаксисом – cat 1 March 2016 в 03:39
  • 2
    Почему так много способов написать одно и то же? !! & GT; _ & л; Мне не нравится этот язык – Awesome_girl 23 June 2016 в 14:33
  • 3
    и победитель - ;(function(){}()); – Roko C. Buljan 27 March 2017 в 23:45
  • 4
    Замечание о предпочтении Крокфорда было очень полезно - объясняет различия, которые я видел в дикой природе, например. jQuery tiny-pubsub gist переключился с одной версии на другую (вы можете увидеть изменение в конце файла), и я не мог понять, почему. – icc97 9 June 2017 в 07:24
  • 5
    Рад, что он предоставил различные варианты синтаксиса. Было бы неплохо, как @Awesome_girl сказал, если было меньше способов сделать то же самое ... но, я полагаю, многие из этих методов - это «код гольфа». способы использования операторов способами, которые обычно не используются; часто для минимизации количества кода. – The Red Pea 9 June 2017 в 19:34

Автономная анонимная функция.

Один короткий и фиктивный пример, где это полезно:

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

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

3
ответ дан usoban 15 August 2018 в 16:29
поделиться
  • 1
    Как указано, ваш поиск перестраивает список для каждого вызова. Чтобы этого избежать, вам необходимо (1) составить список и (2) вернуть функцию поиска в качестве закрывающейся, имеющей доступ к только что созданному списку. Это можно сделать легко, используя анонимную форму для самостоятельного вызова. См. jsfiddle.net/BV4bT . – George 6 September 2013 в 20:14
  • 2
    вы можете объяснить ... меньше накладных расходов .. я не понимаю эту часть – Leonardo Da Codinchi 4 November 2013 в 10:57
  • 3
    Накладные расходы означают любую выполненную работу, которая не является необходимой. Заполнение массива при каждом вызове функции не требуется, поэтому массив в примере заполняется self-exec. анонимная функция в первый раз. Однако, похоже, я допустил ошибку в своем собственном ответе, см. Ссылку в комментарии Джорджа для правильного примера. – usoban 5 November 2013 в 20:50
6
ответ дан Peter Mortensen 5 September 2018 в 15:34
поделиться
18
ответ дан stuart_mad 5 September 2018 в 15:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: