Что такое конструкция (function () {}) () в JavaScript?

793

Раньше я знал, что это значит, но сейчас я борюсь ...

Это в основном говорит document.onload?

(function () {

})();
Exitos
источник
20
Кстати, хотя вы увидите, что люди называют эту функцию «вызывающей себя», это явно не так. Термин Iife имеет преимущество точности.
AakashM
6
Это дает отличное объяснение этой конструкции. Здесь также возник термин «IIFE». benalman.com/news/2010/11/…
jeremysawesome
2
Для именования этой конструкции также посмотрите здесь . Прочитайте о назначении этой конструкции и техническом объяснении (также здесь ). Для синтаксиса, посмотрите, почему скобки необходимы и куда они должны идти .
Берги

Ответы:

855

Это выражение с немедленным вызовом функции , или сокращенно 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)

Исправление, предложенное Гуффой :

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

Обновление Поскольку это довольно популярная тема, стоит упомянуть, что IIFE также может быть написано с помощью функции стрелки ES6 (как Гаджус указал в комментарии ):

((foo) => {
 // do something with foo here foo
})('foo value')
gion_13
источник
@ gion_13 В чем разница между фазой создания и фазой разбора?
akantoword
1
@jlei, как я понимаю, жизненный цикл js-программы включает в себя следующие этапы: синтаксический анализ, создание / компиляция, выполнение. Хотя фактическая реализация (и именование :))) может отличаться в разных браузерах, мы можем определить эти фазы в нашем коде, следя за ошибками синтаксического анализа, подъема и ошибок времени выполнения. Лично я не нашел много ресурсов по этому вопросу, потому что это слишком низкий уровень, и это не то, что программист может контролировать. Вы можете найти какое-то объяснение в этом посте SO: stackoverflow.com/a/34562772/491075
gion_13
@ sam firat всего, есть объявление varianle и новое ключевое слово. Это означает, что в вашем примере вы создаете новый объект, определенный его конструктором (выражение анонимной функции), и он вызывается с помощью оператора new, а не путем вызова функции как в примере IIFE. Конечно, эта функция действует как закрытие для своего содержимого, но это совершенно другой вариант использования.
gion_13
Как это загрязняет глобальное пространство имен? foo не доступен вне функции в любом случае. function(){ var foo = '5'; }
Панкадж
1
@Pankaj - взятый сам по себе, это даже не синтаксически допустимый JS (это выражение функции, но не в контексте выражения, поэтому рассматривается как синтаксическая ошибка).
Квентин
110

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

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

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

В jQuery есть похожая конструкция, о которой вы можете подумать:

$(function(){
});

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

$(document).ready(function(){
});

Но вышеупомянутые две конструкции не являются IIFE .

Guffa
источник
83
Последние два на самом деле не являются IIFE, так как они вызываются, когда DOM готов и не сразу
svvac
15
@swordofpain: Да, это правильно, они не IIFE.
Гуффа
@swordofpain с учетом второго фрагмента; Будет ли какое-либо значение в add () в конце функции, превратив его в IIFE?
Timebandit
Нужна ли точка с запятой в конце?
FrenkyB
@FrenkyB Не обязательно, нет, но рекомендуется (точки с запятой часто не нужны в Javascript, но это хорошая практика). Каждое из этих утверждений содержит анонимные функции, а не объявления функций.
Ледивин
52

Вызов функции с немедленным вызовом (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
令狐 葱
источник
4
последний 31.new'неверный синтаксис
кошка
9
Почему так много способов написать одно и то же? !! > _ <Мне не нравится этот язык
Awesome_girl
6
Победитель;(function(){}());
Роко С.
Объяснение предпочтений Крокфорда было очень полезным - оно объясняет различия, которые я видел в дикой природе, например, суть jQuery tiny-pubsub переключилась с одной версии на другую (вы можете увидеть изменения в конце файла), и я не смог ' не понимаю, почему.
icc97
1
@Awesome_girl: Дело не в том, что есть много способов написать одно и то же; Дело в том, что JS имеет свободную систему типов с операторами, которые могут работать с любым типом значений. Вы можете сделать, 1 - 1и вы можете так же легко сделать true - function(){}. Это только одна вещь (оператор вычитания инфикса), но с другими, даже бессмысленными операндами.
31

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

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);
solendil
источник
Я предполагаю, что «аргументы» - это внешние переменные, на которые ссылаются как «аргументы», для использования в локальном контексте внутри функции?
Далибор
@Dalibor argumentsявляется особенным ; я думаю, что ответчик только что перевернул, где имена идут
кот
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

Скрипка: http://jsfiddle.net/maniator/LqvpQ/


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

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

alert(val); //18
Нафтали ака Нил
источник
1
Я не понимаю, что это доказывает, что он вызывает себя?
Exitos
1
@Exitos, потому что он возвращает эту функцию. Я приведу второй пример.
Нафтали ака Нил
очень легко понять +1
Adiii
24

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

Наиболее распространенный вариант использования:

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

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

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

ES6 Альтернатива (рекомендуется)

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

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

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

В этом примере мы использовали letопределение countпеременной, countограничивающей блок кода, который мы создали с помощью фигурных скобок {...}.

Я называю это «Кудрявая тюрьма».

Усман
источник
10
Мне нравится название Curly Jail . Может быть, это будет придерживаться :)
gion_13
15
(function () {
})();

Это называется IIFE (выражение для немедленного вызова функции). Один из известных шаблонов проектирования JavaScript, это сердце и душа современного шаблона Module. Как следует из названия, он выполняется сразу после его создания. Этот шаблон создает изолированную или закрытую область выполнения.

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

Имитировать блокобзор с помощью IIFE

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

(function (globalObj) {
//Access the globalObj
})(window);
Гуручаран М.К.
источник
Спасибо за предоставленную суть, чтобы понять вторую скобку в IIFE. Кроме того, для уточнения поиска временной выгоды глобальной переменной, определив их в определении
ARSAL
12

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

(...)();

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

function() {}

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

Альдо Стракваданио
источник
11

Это выражение немедленного вызова функции в Javascript:

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

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

greet('Santosh');

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

3. Сразу же вызванное выражение функции:

Пример:

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

console.log(greeting)  // Namaste Santosh. 

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

Типичный пример использования IIFE в JS:

Следующий шаблон IIFE довольно часто используется.

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

Таким образом, эта функция создается и выполняется одновременно (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 помогает нам писать безопасный код, в котором мы не случайно сталкиваемся с глобальными объектами.

Сантош Пиллаи
источник
Если мы создаем функции внутри IIFE, как мы можем получить к ним доступ в каком-либо другом файле js или jsx, то есть в компоненте реагирования.
каменная скала
Даже если мы не использовали IIFE, переменная приветствия не будет сталкиваться с глобальной переменной приветствия. Так в чем же преимущество?
Вилли Дэвид младший
6

Это вызывающая себя анонимная функция .

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

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

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

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

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

Джеймс Хилл
источник
3
(function named(){console.log("Hello");}());<- самовыполняющаяся именованная функция
bryc
@ bryc, почему ты назвал функцию, которой не нужно имя?
Рикардо Гонсалес
2
@RicardoGonzales Рекурсия, я думаю,
bryc
6

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

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

(function(obj){
    // Do something with this obj
})(object);

Здесь «объект», который вы передаете, будет доступен внутри функции через obj, так как вы захватываете его в сигнатуре функции.

Md. Mahbubul Haque
источник
2
На этот вопрос уже есть принятый ответ, и ваш ответ не добавляет ничего, что еще не было охвачено принятым ответом. Следовательно, не было абсолютно никакой необходимости писать этот ответ.
Аадит М Шах
3
Мне нравится читать несколько ответов, иногда формулировка одного или другого имеет значение.
Я думал, что это добавило, потому что это дало мне знать, для чего был этот второй набор скобок. По крайней мере, здесь было яснее, что я видел.
Джонни
Мой любимый Оба конца образца IIFE имеют параметры, и отображение между ними делается простым.
Стивен У. Райт
4

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

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*

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

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);
})();

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

Джим Флуд
источник
2
Синтаксическая ошибка говорит о функциях стрелок. Как я понимаю, это новая особенность js, и ее не было несколько лет назад, а IIFE. Итак, скобки, вероятно, использовались изначально, чтобы избежать синтаксической ошибки, но другой?
JCarlosR
Не могли бы вы ответить на вопрос @JCarlos? Поскольку он совершенно справедливо указывает на то, что IIFE появился намного раньше функции стрелки, это помогло бы понять, почему требуется перенос.
Script47
@ Script47 У меня нет ответа на вопрос JCarlos в комментарии. Вы можете сформулировать новый вопрос и опубликовать его, и я уверен, что вы получите хорошие ответы.
Джим Флад
@JCarlos, когда я выполняю ту, которая выдает ошибку, я фактически получаю, Uncaught SyntaxError: Unexpected token )а не любое упоминание о функции стрелки. Не могли бы вы поделиться с ней скрипкой, выдавшей ошибку функции стрелки?
Script47
2

Самоисполняющаяся анонимная функция. Он выполняется, как только он создан.

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

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);

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

usoban
источник
1
Как написано, ваш поиск перестраивает список при каждом вызове. Чтобы избежать этого, вам нужно (1) составить список и (2) вернуть функцию поиска как замыкание, имеющее доступ к только что созданному вами списку. Это вы можете легко сделать, используя анонимную самопризывающую форму. См. Jsfiddle.net/BV4bT .
Джордж
Можете ли вы объяснить ... меньше накладных расходов ... я не понимаю эту часть
ХИРА ТАКУР
2
Накладные расходы означают любую выполненную работу, которая не является необходимой. Заполнение массива при каждом вызове функции не является необходимым, поэтому массив в примере заполняется самозаполнением. анонимная функция только в первый раз. Однако, похоже, что я допустил ошибку в своем собственном ответе, см. Ссылку в комментарии Джорджа для правильного примера.
Усобан
2

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

Код

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

производит этот вывод:

2
1

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

Даниил
источник
1
Правильно, вывод будет 2, а затем 1, потому что myVar будет запущен первым
Далибор
1
Ваше объяснение хорошо объясняет область действия функции, но не объясняет, почему она выполняется немедленно. Присвоение этой переменной саморазрушительно и может также предполагать, что она может быть выполнена более одного раза. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Будет иметь тот же результат.
Domenicr
2

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

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

источник
1

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

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

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

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

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

bpjoshi
источник
1

Еще один вариант использования - это запоминание, при котором объект кэша не является глобальным:

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();
Шишир Арора
источник
0

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

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

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

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

abdulbarik
источник
0

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

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

Очень круто.

kiwicomb123
источник
0

Следующий код:

(function () {

})();

называется немедленно вызывается функция выражения (IIFE).

Это называется выражением функции, потому что ( yourcode )оператор в Javascript принудительно превращает его в выражение. Разница между выражением функции и функции декларации заключается в следующем:

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

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

После того, как у нас есть выражение, которое оценивает функциональный объект, мы можем немедленно вызвать функциональный объект с ()оператором. Например:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

Почему это полезно?

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

Виллем ван дер Веен
источник
0

В синтаксисе ES6 (постинг для себя, поскольку я продолжаю заходить на эту страницу в поисках быстрого примера):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)
S ..
источник
0

Эта функция называется функцией самовозбуждения. Самовозвратная (также называемая самоисполняющаяся) функция - это безымянная (анонимная) функция, которая вызывается (вызывается) сразу после ее определения. Узнайте больше здесь

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

Вот пример:

(function() {
    var x = 5 + 4;
    console.log(x);
})();


источник
0

Это более подробное объяснение того, почему вы должны использовать это:

«Основная причина использования IIFE состоит в том, чтобы обеспечить конфиденциальность данных. Поскольку переменная JavaScript использует переменные для их содержащей функции, внешний мир не может получить доступ к любым переменным, объявленным в IIFE».

http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html

Томас Уильямс
источник
0

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

Шаг 1: Определите функцию

function add (a, b){
    return a+b;
}
add(5,5);

Шаг 2: Вызовите функцию, заключив объявление всей функции в круглые скобки.

(function add (a, b){
    return a+b;
})
//add(5,5);

Шаг 3: Для немедленного вызова функции просто удалите текст «добавить» из вызова.

(function add (a, b){
    return a+b;
})(5,5);

Основная причина использования IFFE состоит в том, чтобы сохранить частную область действия в вашей функции. Внутри вашего JavaScript-кода вы хотите убедиться, что вы не переопределяете ни одну глобальную переменную. Иногда вы можете случайно определить переменную, которая переопределяет глобальную переменную. Давайте попробуем на примере. Предположим, у нас есть HTML-файл с именем iffe.html и коды внутри тега body:

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

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

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

вы в конечном итоге в SyntaxError : документа глобального свойства.

Но если вы хотите объявить переменную имени документа, вы можете сделать это с помощью IFFE.

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Вывод:

введите описание изображения здесь

Давайте попробуем на другом примере, предположим, у нас есть объект калькулятора, как показано ниже:

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

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

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

да, вы получите ошибку TypeError: calculator.mul не является функцией iffe.html

Но с помощью IFFE мы можем создать частную область видимости, где мы можем создать еще один калькулятор имен переменных и использовать его;

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

Вывод: введите описание изображения здесь

повелитель
источник
-1

Я думаю, что 2 набора скобок немного запутывают, но я видел другое использование в примере с 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 {}
Джеймс Лин
источник
-1

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

KawaiKx
источник
-1

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

Мы можем создать IIFE двумя способами

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

ИЛИ

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

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

Риной Ашокан
источник