Раньше я знал, что это значит, но сейчас я борюсь ...
Это в основном говорит document.onload
?
(function () {
})();
Раньше я знал, что это значит, но сейчас я борюсь ...
Это в основном говорит document.onload
?
(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)
Исправление, предложенное Гуффой :
Функция выполняется сразу после ее создания, а не после ее анализа. Весь блок скрипта анализируется перед выполнением любого кода в нем. Кроме того, анализ кода не означает автоматически, что он выполняется, если, например, IIFE находится внутри функции, он не будет выполняться до тех пор, пока функция не будет вызвана.
Обновление Поскольку это довольно популярная тема, стоит упомянуть, что IIFE также может быть написано с помощью функции стрелки ES6 (как Гаджус указал в комментарии ):
((foo) => {
// do something with foo here foo
})('foo value')
function(){ var foo = '5'; }
Это просто анонимная функция, которая выполняется сразу после ее создания.
Это так же, как если бы вы присвоили его переменной и использовали сразу после этого, только без переменной:
var f = function () {
};
f();
В jQuery есть похожая конструкция, о которой вы можете подумать:
$(function(){
});
Это краткая форма привязки ready
события:
$(document).ready(function(){
});
Но вышеупомянутые две конструкции не являются IIFE .
Вызов функции с немедленным вызовом (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
31.new
'неверный синтаксис
;(function(){}());
1 - 1
и вы можете так же легко сделать true - function(){}
. Это только одна вещь (оператор вычитания инфикса), но с другими, даже бессмысленными операндами.
Он объявляет анонимную функцию, затем вызывает ее:
(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
не будет вытекать из функции. Вы должны получить 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
ограничивающей блок кода, который мы создали с помощью фигурных скобок {...}
.
Я называю это «Кудрявая тюрьма».
(function () {
})();
Это называется IIFE (выражение для немедленного вызова функции). Один из известных шаблонов проектирования JavaScript, это сердце и душа современного шаблона Module. Как следует из названия, он выполняется сразу после его создания. Этот шаблон создает изолированную или закрытую область выполнения.
В JavaScript до ECMAScript 6 использовалась лексическая область видимости, поэтому IIFE использовался для имитации блока. (С ECMAScript 6 блок - обзорное возможно с введением let
и const
ключевых слов.)
Справочник по проблеме с лексической области видимости
Имитировать блокобзор с помощью IIFE
Выигрыш в производительности использования IIFE является способность передавать часто используемые глобальные объекты , такие как window
, document
и т.д. в качестве аргумента за счет уменьшения поиск области видимости. (Помните, что JavaScript ищет свойства в локальной области видимости и поднимается по цепочке до глобальной области видимости). Таким образом, доступ к глобальным объектам в локальной области сокращает время поиска, как показано ниже.
(function (globalObj) {
//Access the globalObj
})(window);
Нет, эта конструкция просто создает область для именования. Если разбить его на части, вы увидите, что у вас есть внешний
(...)();
Это вызов функции. Внутри скобки у вас есть:
function() {}
Это анонимная функция. Все, что объявлено с помощью var внутри конструкции, будет видно только внутри той же конструкции и не будет загрязнять глобальное пространство имен.
Это выражение немедленного вызова функции в Javascript:
Чтобы понять IIFE в JS, давайте разберем его:
a = 10 output = 10 (1+3) output = 4
// 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 помогает нам писать безопасный код, в котором мы не случайно сталкиваемся с глобальными объектами.
Это вызывающая себя анонимная функция .
Ознакомьтесь с объяснением самопризывной функции в W3Schools .
Выражения функций могут быть сделаны «самовывозными».
Вызывающее себя выражение вызывается (запускается) автоматически, без вызова.
Выражения функций будут выполняться автоматически, если за выражением следует ().
Вы не можете самостоятельно вызывать объявление функции.
(function named(){console.log("Hello");}());
<- самовыполняющаяся именованная функция
Это вызывающая себя анонимная функция. Он выполняется, пока он определен. Это означает, что эта функция определена и вызывает себя сразу после определения.
И объяснение синтаксиса таково: функция в первой ()
круглой скобке - это функция, у которой нет имени, и по следующей ();
круглой скобке вы можете понять, что она вызывается во время ее определения. И вы можете передать любой аргумент во второй ()
скобке, который будет взят в функции, которая находится в первой скобке. Смотрите этот пример:
(function(obj){
// Do something with this obj
})(object);
Здесь «объект», который вы передаете, будет доступен внутри функции через obj, так как вы захватываете его в сигнатуре функции.
Начните здесь:
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);
})();
Это не должно быть более сложным, чем это.
Uncaught SyntaxError: Unexpected token )
а не любое упоминание о функции стрелки. Не могли бы вы поделиться с ней скрипкой, выдавшей ошибку функции стрелки?
Самоисполняющаяся анонимная функция. Он выполняется, как только он создан.
Один короткий и фиктивный пример, где это полезно:
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 same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name);
Будет иметь тот же результат.
Это называется 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);
})();
IIFE (немедленно вызванное выражение функции) - это функция, которая выполняется, как только скрипт загружается и уходит.
Рассмотрим функцию ниже, написанную в файле с именем iife.js
(function(){
console.log("Hello Stackoverflow!");
})();
Этот код выше будет выполняться, как только вы загрузите iife.js и напечатает « Hello Stackoverflow!». на консоли инструментов разработчика.
Подробное объяснение см. В разделе « Вызов функции с немедленным вызовом» (IIFE).
Еще один вариант использования - это запоминание, при котором объект кэша не является глобальным:
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 () {...} преобразует код внутри скобок в выражение. Вторая пара скобок вызывает функцию, полученную из выражения.
Ан IIFE
также может быть описан как самовывозная анонимная функция. Его наиболее распространенное использование - ограничить область действия переменной, создаваемой через var, или инкапсулировать контекст, чтобы избежать конфликтов имен.
Причина того, что используются вызывающие себя анонимные функции, заключается в том, что они никогда не должны вызываться другим кодом, поскольку они «настраивают» код, который должен вызываться (наряду с предоставлением области видимости функциям и переменным).
Другими словами, они похожи на программы, которые «создают классы» в начале программы. После того, как они были созданы (автоматически), единственными доступными функциями являются те, которые возвращаются анонимной функцией. Однако все остальные » скрытые 'функции все еще там, наряду с любым состоянием (переменные, установленные во время создания области видимости).
Очень круто.
Следующий код:
(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 . Это уменьшает шансы на конфликты имен и позволяет вам назвать их более небрежно (например, вам не нужно префиксировать их).
Эта функция называется функцией самовозбуждения. Самовозвратная (также называемая самоисполняющаяся) функция - это безымянная (анонимная) функция, которая вызывается (вызывается) сразу после ее определения. Узнайте больше здесь
Что эти функции делают, так это то, что когда функция определена, функция вызывается немедленно, что экономит время и дополнительные строки кода (по сравнению с вызовом ее в отдельной строке).
Вот пример:
(function() {
var x = 5 + 4;
console.log(x);
})();
Это более подробное объяснение того, почему вы должны использовать это:
«Основная причина использования IIFE состоит в том, чтобы обеспечить конфиденциальность данных. Поскольку переменная JavaScript использует переменные для их содержащей функции, внешний мир не может получить доступ к любым переменным, объявленным в IIFE».
Это выражение функции, оно обозначает выражение «немедленно вызванная функция» (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>
Я думаю, что 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 {}
Обычно код JavaScript имеет глобальную область применения. Когда мы объявляем глобальную переменную в ней, есть шанс использовать ту же самую дублирующую переменную в какой-то другой области разработки для какой-то другой цели. Из-за этого дублирования может произойти какая-то ошибка. Таким образом, мы можем избежать этих глобальных переменных с помощью немедленного вызова выражения функции, это выражение является самоисполняющимся выражением. Когда мы создаем наш код внутри этого IIFE выражением. выражения глобальная переменная будет похожа на локальную область видимости и локальную переменную.
Мы можем создать IIFE двумя способами
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
ИЛИ
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
В приведенном выше фрагменте кода « var app » теперь является локальной переменной.