Что такое конструкция (function () {}) () в JavaScript?
раньше я знал, что это значит, но теперь я борюсь...
это в основном говорят document.onload
?
(function () {
})();
23 ответов
Это Немедленно Вызванное Выражение Функции или жизнь для краткости. Он выполняется сразу после создания.
Он не имеет ничего общего с любым обработчиком событий для любых событий (например,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
эта конструкция называется немедленно вызывается выражение функции (IIFE) что означает, что он выполняется немедленно. Подумайте об этом как о функции, вызываемой автоматически, когда интерпретатор достигает этой функции.
наиболее распространенный вариант использования:
одним из наиболее распространенных вариантов использования является ограничение области переменной, сделанной через var
. Переменные, созданные с помощью var
имеют область, ограниченную функцией, поэтому эта конструкция (которая является оболочкой функции вокруг определенного кода) убедитесь, что ваша область переменных не вытекает из этой функции.
в следующем примере count не будет доступен вне немедленно вызываемой функции, т. е. области count
не будет вытекать из функции. Вы должны получить Reference Error
, если вы попытаетесь получить доступ к нему вне немедленно вызванной функции в любом случае.
(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); // Reference Error: count is not defined
в этом примере мы использовали let
определение count
переменной, которая делает count
ограничивается блок кода, который мы создали с помощью фигурных скобок {...}
.
я называю это Curly Jail
.
(function () {
})();
Это называется IIFE (немедленно вызывается выражение функции). Один из известных шаблонов дизайна javascript, и это сердце и душа современного шаблона модуля дня. Как следует из названия, он выполняется сразу после его создания. Этот шаблон создает изолированную или закрытую область выполнения.
JavaScript до ECMAScript 6 с использованием лексической области, IIFE используется для моделирования области блока. (С блоком ECMAScript 6 область видимости возможна с введение ключевого слова let и const.) Ссылка для вопроса с лексическим охватом
имитация блок обзора при жизни
преимущество в производительности использования IIFE-это возможность передавать часто используемые глобальные объекты, такие как окно, документ и т. д. В качестве аргумента, уменьшив область поиска.(Помните, что Javascript ищет свойство в локальной области и вверх по цепочке до глобальной области). Таким образом, доступ к глобальным объектам в локальной области время поиска, как показано ниже.
(function (globalObj) {
//Access the globalObj
})(window);
нет, эта конструкция просто создает область для именования. Если вы сломаете его на части, вы увидите, что у вас есть внешний
(...)();
это вызов функции. Внутри скобки у вас есть:
function() {}
это анонимная функция. Все, что объявлено с var внутри конструкции будет виден только внутри той же конструкции и не будет загрязнять глобальное пространство имен.
Что это само-вызов анонимной функции.
Проверьте W3Schools объяснение самозванной функции.
выражения функции можно сделать "само-вызывать".
самозваное выражение вызывается (запускается) автоматически, без называется.
выражения функций будут выполняться автоматически, если выражение затем ().
вы не можете self-invoke объявление функции.
это немедленно вызываемое выражение функции в Javascript:
чтобы понять IIFE в JS, давайте разберем его:
-
выражение: что-то, что возвращает значение
Пример: попробуйте следующее в консоли chrome. Эти выражения в JS.
a = 10 output = 10 (1+3) output = 4
-
Выражение Функции:
Пример:
// Function Expression var greet = function(name){ return 'Namaste' + ' ' + name; } greet('Santosh');
как работает выражение функции:
- Когда JS engine запускается в первый раз (контекст выполнения - фаза создания), эта функция (справа от = выше) не выполняется или не сохраняется в памяти. Переменной 'greet' присваивается значение' undefined ' движком 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 довольно часто используется.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
- мы делаем здесь две вещи.
а) оборачивать нашу функцию выражение внутри фигурных скобок (). Это говорит синтаксическому анализатору, что все, что находится внутри (), является выражением (в данном случае выражением функции) и является допустимым кодом.
b) мы вызываем этот funtion в то же время, используя () в конце его.
таким образом, эта функция создается и выполняется одновременно (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 помогает нам написать безопасный код, где мы не сталкиваемся с глобальными объектами непреднамеренно.
это самозваная анонимная функция. Он выполняется, пока он определен. Это означает, что эта функция определена и вызывает себя сразу после определения.
и объяснение синтаксиса: функция в пределах первого ()
скобки-это функция, которая не имеет имени, а по следующему ();
скобки вы можете понять, что он вызывается в то время, когда он определен. И вы можете передать любой аргумент в эту секунду ()
скобочки, которые будут быть схваченным в функции, которая находится в первой скобке. См. этот пример:
(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! на консоли инструменты разработчика.
подробное объяснение см. В разделе Сразу-Вызывается Функция Выражения (IIFE)
еще один вариант использования-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];
}
}
})();
Это анонимная функция что это self invoking. Обычно известный как немедленно вызываемое выражение функции (IIFE).
немедленно вызываемое выражение функции (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 имеет глобальную область в приложении. Когда мы объявляем глобальную переменную в ней, есть шанс использовать ту же самую дублирующую переменную в какой-то другой области разработки для какой-то другой цели. Из-за этого дублирования может произойти некоторая ошибка. Таким образом , мы можем избежать этих глобальных переменных, используя немедленно вызывающее выражение функции, это выражение является самоисполняющимся выражением.Когда мы делаем наш код внутри жизнь выражение глобального переменная будет похожа на локальную область и локальную переменную.
двухсторонний мы можем создать жизнь
(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. Это уменьшает вероятность конфликтов именования и позволяет вам называть их более небрежно (например, вам не нужно префиксировать их).