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


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

это в основном говорят document.onload?

(function () {

})();
23 615

23 ответа:

Это Немедленно Вызванное Выражение Функции или IIFE для краткости. Он выполняется сразу после его создания.

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

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

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

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

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

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

$(function(){
});

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

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

немедленно вызываемое выражение функции (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

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

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

то есть выполнить немедленно.

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

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

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

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

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

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

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

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

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

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

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

я называю это Curly Jail.

(function () {
})();

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

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

имитация области блока с помощью IIFE

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

(function (globalObj) {
//Access the globalObj
})(window);

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

(...)();

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

function() {}

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

Что это само-вызов анонимной функции.

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

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

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

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

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

это немедленно вызываемое выражение функции в 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 engine запускается в первый раз (выполнение Context - Create Phase), эта функция (справа от = выше) не выполняется и не сохраняется в памяти. Переменная 'приветствовать' назначен 'неопределено' стоимость двигателя на JS.
- Во время выполнения (контекст выполнения-фаза выполнения) объект funtion создается на лету (его не пока выполняется), присваивается переменной 'greet', и она может быть вызвана с помощью 'greet('somename')'.

3. Немедленно Вызывается Выражение Funtion:

пример:

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

console.log(greeting)  // Namaste Santosh. 

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

типичный случай использования IIFE в JS:

следующая закономерность жизни довольно часто используется.

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

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

важный usecase для 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 помогает нам написать безопасный код, где мы не сталкиваемся с глобальными объектами непреднамеренно.

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

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

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

здесь "объект", который вы передаете, будет доступен в функции с помощью "obj", поскольку вы захватываете его в сигнатуре функции.

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

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

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

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

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

код

var same_name = 1;

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

console.log(same_name);

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

2
1

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

Начало здесь:

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

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

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

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

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

этот код выше будет выполняться, как только вы загрузите iife.JS и будет печатать 'Привет Stackoverflow! на консоли инструменты разработчика.

подробное объяснение см. Сразу-Вызывается Функция Выражения (Жизнь)

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

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

Это анонимная функция что это самостоятельного вызова. Известный как сейчас вызывается функция выражения (жизнь).

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

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

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

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

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

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

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

Object {}
Object {}

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

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

очень круто.

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

два способа мы можем создать IIFE

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

или

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

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

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

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

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

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

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

(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. Это уменьшает вероятность конфликтов имен и позволяет называть их более небрежно (например, вам не нужно их префикс).