Раніше я знав, що це означає, але я зараз борюся ...
Це в основному говорить 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)
Корекція, запропонована Guffa :
Функція виконується відразу після її створення, а не після її розбору. Весь блок скриптів аналізується до того, як буде виконаний будь-який код у ньому. Крім того, аналіз коду не означає автоматично, що він виконується, якщо, наприклад, 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
Fiddle: 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, це серце і душа сучасного шаблону модулів. Як випливає з назви, воно виконується відразу після його створення. Ця закономірність створює ізольований або приватний обсяг виконання.
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 працює вперше (контекст виконання - створення фази), ця функція (з правого боку = вище) не виконується і не зберігається в пам'яті. Двигун JS змінній "привіт" присвоює значення "невизначене".
- Під час виконання (Execution Context - Execute phase) об’єкт функції створюється на льоту ( його ще не виконано ), присвоюється змінній 'привіт' і його можна викликати за допомогою 'вітаю (' якесь ім'я ')'.
3. Виявлення функцій негайно:
Приклад:
// IIFE
var greeting = function(name) {
return 'Namaste' + ' ' + name;
}('Santosh')
console.log(greeting) // Namaste Santosh.
Як працює IIFE :
- Зверніть увагу на (()) відразу після оголошення функції. Кожен об’єкт функціонування має до нього властивість "CODE", яку можна викликати. І ми можемо назвати це (або викликати його), використовуючи брекети '()'.
- Отже, тут під час виконання (Execution Context - Execute Phase) створюється об’єкт функції та виконується його одночасно.
Отже, тепер змінна привітання, замість об'єкта функції, має своє повернене значення (рядок)
Типовий випадок використання 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, і надрукує " Привіт 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
// ...
})();
Перша пара дужок функція () {...} перетворює код усередині дужок у вираз. Друга пара дужок викликає функцію, отриману в результаті виразу.
А 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,
Крок 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>
Ну, вищезгаданий код буде виконуватись із будь-яким питанням, тепер припустимо, що ви скасуєте змінну з ім'ям документа випадково чи навмисно.
<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>
Я думаю, що два набори дужок робить це дещо заплутаним, але я бачив ще одне використання у прикладі 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 {}
Зазвичай код JavaScript має глобальну сферу застосування. Коли ми оголошуємо глобальну змінну в ній, є ймовірність використання тієї ж дублікатної змінної в якійсь іншій області розробки для іншої мети. Через це дублювання може статися якась помилка. Таким чином, ми можемо уникнути цих глобальних змінних, використовуючи негайно виклик функції виразу, цей вираз є самовиконанням виразу. Коли ми робимо наш код всередині цього IIFE виразу. глобальної змінної виразу буде як локальна область дії, так і локальна змінна.
Два способи створити IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
АБО
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
У фрагменті коду вище " var app " є локальною змінною.