Je savais ce que cela signifiait, mais je me bats maintenant ...
Est-ce à dire essentiellement document.onload
?
(function () {
})();
Je savais ce que cela signifiait, mais je me bats maintenant ...
Est-ce à dire essentiellement document.onload
?
(function () {
})();
Réponses:
C'est une expression de fonction immédiatement invoquée , ou IIFE pour faire court. Il s'exécute immédiatement après sa création.
Cela n'a rien à voir avec un gestionnaire d'événements pour des événements (tels que document.onload
).
Considérez la partie dans la première paire de parenthèses: .... c'est une expression de fonction régulière. Regardez ensuite la dernière paire , celle-ci est normalement ajoutée à une expression pour appeler une fonction; dans ce cas, notre expression préalable.(function(){})();
(function(){})();
Ce modèle est souvent utilisé lorsque vous essayez d'éviter de polluer l'espace de noms global, car toutes les variables utilisées à l'intérieur de l'IIFE (comme dans toute autre fonction normale ) ne sont pas visibles en dehors de sa portée.
C'est pourquoi, peut-être, vous avez confondu cette construction avec un gestionnaire d'événements pour window.onload
, car il est souvent utilisé comme ceci:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
Correction suggérée par Guffa :
La fonction est exécutée juste après sa création, pas après son analyse. L'ensemble du bloc de script est analysé avant l'exécution de tout code qu'il contient. En outre, l'analyse de code ne signifie pas automatiquement qu'elle est exécutée, si par exemple l'IIFE est à l'intérieur d'une fonction, il ne sera pas exécuté jusqu'à ce que la fonction soit appelée.
Mise à jour Comme il s'agit d'un sujet assez populaire, il convient de mentionner que l'IIFE peut également être écrit avec la fonction de flèche d' ES6 (comme Gajus l' a souligné dans un commentaire ):
((foo) => {
// do something with foo here foo
})('foo value')
function(){ var foo = '5'; }
C'est juste une fonction anonyme qui est exécutée juste après sa création.
C'est comme si vous l'attribuiez à une variable et l'utilisiez juste après, uniquement sans la variable:
var f = function () {
};
f();
Dans jQuery, il existe une construction similaire à laquelle vous pourriez penser:
$(function(){
});
C'est la forme courte de lier l' ready
événement:
$(document).ready(function(){
});
Mais les deux constructions ci-dessus ne sont pas des IIFE .
Une expression de fonction immédiatement invoquée (IIFE) appelle immédiatement une fonction. Cela signifie simplement que la fonction est exécutée immédiatement après l'achèvement de la définition.
Trois formulations plus courantes:
// 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.');
}();
S'il n'y a pas d'exigences particulières pour sa valeur de retour, alors nous pouvons écrire:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Alternativement, cela peut être:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
Vous pouvez même écrire:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required
31.new
'est une syntaxe invalide
;(function(){}());
1 - 1
et vous pouvez le faire tout aussi facilement true - function(){}
. Ce n'est qu'une chose (un opérateur de soustraction infixe) mais avec des opérandes différents, voire absurdes.
Il déclare une fonction anonyme, puis l'appelle:
(function (local_arg) {
// anonymous function
console.log(local_arg);
})(arg);
Cela signifie exécuter immédiatement.
donc si je le fais:
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
Violon: http://jsfiddle.net/maniator/LqvpQ/
var val = (function(){
return 13 + 5;
})();
alert(val); //18
Cette construction est appelée une expression de fonction immédiatement invoquée (IIFE), ce qui signifie qu'elle est exécutée immédiatement. Considérez-le comme une fonction appelée automatiquement lorsque l'interprète atteint cette fonction.
Cas d'utilisation le plus courant:
L'un de ses cas d'utilisation les plus courants est de limiter la portée d'une variable effectuée via var
. Les variables créées via var
ont une portée limitée à une fonction, de sorte que cette construction (qui est un wrapper de fonction autour de certains codes) s'assurera que votre portée de variable ne s'échappe pas de cette fonction.
Dans l'exemple suivant, count
ne sera pas disponible en dehors de la fonction immédiatement invoquée, c'est-à-dire que la portée de count
ne sortira pas de la fonction. Vous devriez obtenir un ReferenceError
, si vous essayez quand même d'y accéder en dehors de la fonction immédiatement invoquée.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
Alternative ES6 (recommandé)
Dans ES6, nous pouvons désormais créer des variables via let
et const
. Les deux ont une portée de bloc (contrairement à la var
portée de fonction).
Par conséquent, au lieu d'utiliser cette construction complexe de IIFE pour le cas d'utilisation que j'ai mentionné ci-dessus, vous pouvez maintenant écrire du code beaucoup plus simple pour vous assurer que la portée d'une variable ne s'échappe pas du bloc souhaité.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
Dans cet exemple, nous avons utilisé let
pour définir une count
variable qui se count
limite au bloc de code, nous avons créé avec les accolades {...}
.
Je l'appelle une «prison bouclée».
(function () {
})();
Cela s'appelle IIFE (Immediateely Invoked Function Expression). L'un des célèbres modèles de conception JavaScript, il est le cœur et l'âme du modèle de module moderne. Comme son nom l'indique, il s'exécute immédiatement après sa création. Ce modèle crée un périmètre d'exécution isolé ou privé.
JavaScript avant ECMAScript 6 utilisait la portée lexicale, donc IIFE a été utilisé pour simuler la portée des blocs. (Avec l'ECMAScript 6, la portée des blocs est possible avec l'introduction des mots clés let
et const
.)
Référence pour problème avec la portée lexicale
Simuler la portée d'un bloc avec IIFE
L'avantage de la performance de l' utilisation de Ia vie est la capacité de passer des objets globaux couramment utilisés comme window
, document
, etc. comme argument en réduisant la recherche de portée. (N'oubliez pas que JavaScript recherche les propriétés dans la portée locale et dans la chaîne jusqu'à la portée globale). Ainsi, l'accès aux objets globaux dans la portée locale réduit le temps de recherche comme ci-dessous.
(function (globalObj) {
//Access the globalObj
})(window);
Non, cette construction crée simplement une portée pour la dénomination. Si vous le cassez en plusieurs parties, vous pouvez voir que vous avez un
(...)();
C'est une invocation de fonction. À l'intérieur de la parenthèse, vous avez:
function() {}
C'est une fonction anonyme. Tout ce qui est déclaré avec var à l'intérieur de la construction ne sera visible qu'à l'intérieur de la même construction et ne polluera pas l'espace de noms global.
Il s'agit d'une expression de fonction immédiatement invoquée en Javascript:
Pour comprendre l'IFEF en JS, décomposons-le:
a = 10 output = 10 (1+3) output = 4
// Function Expression var greet = function(name){ return 'Namaste' + ' ' + name; } greet('Santosh');
Comment fonctionne l'expression de fonction:
- Lorsque le moteur JS s'exécute pour la première fois (contexte d'exécution - phase de création), cette fonction (sur le côté droit de = ci-dessus) n'est pas exécutée ni stockée dans la mémoire. La variable «salutation» reçoit une valeur «non définie» par le moteur JS.
- Pendant l'exécution (Contexte d'exécution - Phase d'exécution), l'objet funtion est créé à la volée ( il n'est pas encore exécuté ), est affecté à la variable 'saluer' et il peut être invoqué en utilisant 'saluer (' un nom ')'.
3. Expression Funtion immédiatement invoquée:
Exemple:
// IIFE
var greeting = function(name) {
return 'Namaste' + ' ' + name;
}('Santosh')
console.log(greeting) // Namaste Santosh.
Comment fonctionne l'IFEF :
- Remarquez le '()' immédiatement après la déclaration de fonction. Chaque objet funtion a une propriété 'CODE' attachée qui peut être appelée. Et nous pouvons l'appeler (ou l'invoquer) en utilisant des accolades '()'.
- Donc ici, pendant l'exécution (Contexte d'exécution - Phase d'exécution), l'objet fonction est créé et son exécuté en même temps
- Alors maintenant, la variable de salutation, au lieu d'avoir l'objet funtion, a sa valeur de retour (une chaîne)
Cas d'utilisation typique de IIFE dans JS:
Le modèle IIFE suivant est assez couramment utilisé.
// IIFE
// Spelling of Function was not correct , result into error
(function (name) {
var greeting = 'Namaste';
console.log(greeting + ' ' + name);
})('Santosh');
Cette fonction est donc créée et exécutée en même temps (IIFE).
Cas d'utilisation important pour IIFE:
L'IFEF garde notre code en sécurité.
- IIFE, étant une fonction, a son propre contexte d'exécution, ce qui signifie que toutes les variables créées à l'intérieur sont locales à cette fonction et ne sont pas partagées avec le contexte d'exécution global.
Supposons que j'ai un autre fichier JS (test1.js) utilisé dans mon application avec iife.js (voir ci-dessous).
// 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'.
L'IIFF nous aide donc à écrire du code sûr où nous n'entrons pas en collision involontairement avec les objets globaux.
Il s'agit d'une fonction anonyme auto-invoquante .
Consultez l' explication W3Schools d'une fonction auto-invoquante .
Les expressions de fonction peuvent être rendues «auto-appelantes».
Une expression auto-invoquante est invoquée (démarrée) automatiquement, sans être appelée.
Les expressions de fonction s'exécuteront automatiquement si l'expression est suivie de ().
Vous ne pouvez pas invoquer automatiquement une déclaration de fonction.
(function named(){console.log("Hello");}());
<- fonction nommée auto-
Il s'agit de la fonction anonyme auto-invoquante. Il est exécuté pendant sa définition. Ce qui signifie que cette fonction est définie et s'appelle immédiatement après la définition.
Et l'explication de la syntaxe est: La fonction dans la première ()
parenthèse est la fonction qui n'a pas de nom et par la ();
parenthèse suivante, vous pouvez comprendre qu'elle est appelée au moment où elle est définie. Et vous pouvez passer n'importe quel argument dans cette deuxième ()
parenthèse qui sera saisie dans la fonction qui se trouve dans la première parenthèse. Voir cet exemple:
(function(obj){
// Do something with this obj
})(object);
Ici, «l'objet» que vous passez sera accessible dans la fonction par «obj», comme vous le saisissez dans la signature de la fonction.
Commencer ici:
var b = 'bee';
console.log(b); // global
Mettez-le dans une fonction et il n'est plus global - votre objectif principal.
function a() {
var b = 'bee';
console.log(b);
}
a();
console.log(b); // ReferenceError: b is not defined -- *as desired*
Appelez immédiatement la fonction - oups:
function a() {
var b = 'bee';
console.log(b);
}(); // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'
Utilisez les parenthèses pour éviter une erreur de syntaxe:
(function a() {
var b = 'bee';
console.log(b);
})(); // OK now
Vous pouvez laisser le nom de la fonction:
(function () { // no name required
var b = 'bee';
console.log(b);
})();
Cela n'a pas besoin d'être plus compliqué que cela.
Uncaught SyntaxError: Unexpected token )
plutôt que toute mention de la fonction flèche. Pourriez-vous éventuellement partager un violon en lançant l'erreur de fonction flèche?
Fonction anonyme auto-exécutable. Il est exécuté dès sa création.
Un exemple court et factice où cela est utile est:
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);
Ainsi, au lieu de créer une liste à chaque fois, vous ne la créez qu'une seule fois (moins de surcharge).
Les fonctions auto-exécutables sont généralement utilisées pour encapsuler le contexte et éviter les collusions de noms. Toute variable que vous définissez à l'intérieur de la (fonction () {..}) () n'est pas globale.
Le code
var same_name = 1;
var myVar = (function() {
var same_name = 2;
console.log(same_name);
})();
console.log(same_name);
produit cette sortie:
2
1
En utilisant cette syntaxe, vous évitez d'entrer en collision avec des variables globales déclarées ailleurs dans votre code JavaScript.
var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name);
Aurait le même résultat.
Il est appelé IIFE - Expression de fonction immédiatement invoquée. Voici un exemple pour montrer sa syntaxe et son utilisation. Il est utilisé pour limiter l'utilisation des variables uniquement jusqu'à la fonction et pas au-delà.
(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 (expression de fonction immédiatement invoquée) est une fonction qui s'exécute dès que le script se charge et disparaît.
Considérez la fonction ci-dessous écrite dans un fichier nommé iife.js
(function(){
console.log("Hello Stackoverflow!");
})();
Ce code ci-dessus s'exécutera dès que vous chargerez iife.js et affichera ' Hello Stackoverflow! 'sur la console des outils de développement.
Pour une explication détaillée, voir Expression de fonction immédiatement invoquée (IIFE)
Un autre cas d'utilisation est la mémorisation où un objet de cache n'est pas global:
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];
}
}
})();
Une expression de fonction immédiatement invoquée (IIFE) est une fonction qui est exécutée dès sa création. Il n'a aucun lien avec aucun événement ou exécution asynchrone. Vous pouvez définir un IIFE comme indiqué ci-dessous:
(function() {
// all your code here
// ...
})();
La première paire de parenthèses function () {...} convertit le code à l'intérieur des parenthèses en une expression. La deuxième paire de parenthèses appelle la fonction résultant de l'expression.
An IIFE
peut également être décrit comme une fonction anonyme auto-invoquante. Son utilisation la plus courante consiste à limiter la portée d'une variable créée via var ou à encapsuler le contexte pour éviter les collisions de noms.
La raison pour laquelle des fonctions anonymes auto-évoquantes sont utilisées est qu'elles ne devraient jamais être appelées par un autre code car elles "configurent" le code qui EST censé être appelé (tout en donnant la portée aux fonctions et aux variables).
En d'autres termes, ils sont comme des programmes qui "font des classes", au début du programme. Après avoir été instanciés (automatiquement), les seules fonctions disponibles sont celles renvoyées par la fonction anonyme. Cependant, toutes les autres " les fonctions cachées sont toujours là, avec n'importe quel état (variables définies lors de la création de la portée).
Très cool.
Le code suivant:
(function () {
})();
est appelée expression de fonction immédiatement invoquée (IIFE).
On l'appelle une expression de fonction car l' ( yourcode )
opérateur en Javascript la force dans une expression. La différence entre une expression de fonction et une déclaration de fonction est la suivante:
// declaration:
function declaredFunction () {}
// expressions:
// storing function into variable
const expressedFunction = function () {}
// Using () operator, which transforms the function into an expression
(function () {})
Une expression est simplement un tas de code qui peut être évalué en une seule valeur . Dans le cas des expressions de l'exemple ci-dessus, cette valeur était un objet de fonction unique .
Une fois que nous avons une expression qui s'évalue en un objet fonction, nous pouvons alors invoquer immédiatement l'objet fonction avec l' ()
opérateur. Par exemple:
(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
Lorsque nous avons affaire à une grande base de code et / ou lorsque nous importons diverses bibliothèques, les risques de conflits de noms augmentent. Lorsque nous écrivons certaines parties de notre code qui sont liées (et donc utilisent les mêmes variables) à l'intérieur d'un IIFE, toutes les variables et les noms de fonction sont limités aux crochets de fonction de l'IIFF . Cela réduit les risques de nommer les conflits et vous permet de les nommer plus négligents (par exemple, vous n'avez pas à les préfixer).
Cette fonction est appelée fonction auto-invoquante. Une fonction auto-invoquante (également appelée auto-exécutable) est une fonction sans nom (anonyme) qui est invoquée (appelée) immédiatement après sa définition. En savoir plus ici
Ce que font ces fonctions, c'est que lorsque la fonction est définie, la fonction est immédiatement appelée, ce qui économise du temps et des lignes de code supplémentaires (par rapport à l'appel sur une ligne séparée).
Voici un exemple:
(function() {
var x = 5 + 4;
console.log(x);
})();
Voici une explication plus approfondie de la raison pour laquelle vous utiliseriez ceci:
"La principale raison d'utiliser un IIFE est d'obtenir la confidentialité des données. Étant donné que la var de JavaScript étend les variables à leur fonction contenante, toutes les variables déclarées dans le IIFE ne sont pas accessibles au monde extérieur."
C'est une expression de fonction, elle signifie Immediately Invoked Function Expression (IIFE). IIFE est simplement une fonction qui est exécutée juste après sa création. Si la fonction doit attendre jusqu'à ce qu'elle soit appelée pour être exécutée, IIFE est exécuté immédiatement. Construisons l'exemple IIFE. Supposons que nous ayons une fonction add qui prend deux entiers comme arguments et renvoie la somme permet de transformer la fonction add en IIFE,
Étape 1: définir la fonction
function add (a, b){
return a+b;
}
add(5,5);
Étape 2: appelez la fonction en enveloppant l'intégralité de la déclaration de fonction entre parenthèses
(function add (a, b){
return a+b;
})
//add(5,5);
Étape 3: Pour réactiver immédiatement la fonction, il suffit de supprimer le texte «ajouter» de l'appel.
(function add (a, b){
return a+b;
})(5,5);
La principale raison d'utiliser un IFFE est de conserver une portée privée au sein de votre fonction. Dans votre code javascript, vous voulez vous assurer que vous ne remplacez aucune variable globale. Parfois, vous pouvez accidentellement définir une variable qui remplace une variable globale. Essayons par l'exemple. supposons que nous ayons un fichier html appelé iffe.html et que les codes à l'intérieur de la balise body soient-
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
</body>
Eh bien, le code ci-dessus s'exécutera sans aucune question, supposons maintenant que vous avez redécouvert une variable nommée document accidentellement ou intentionnellement.
<body>
<div id = 'demo'></div>
<script>
document.getElementById("demo").innerHTML = "Hello JavaScript!";
const document = "hi there";
console.log(document);
</script>
</body>
vous vous retrouverez dans un SyntaxError : redéclaration de document de propriété globale non configurable.
Mais si vous souhaitez supprimer un document de nom de variable, vous pouvez le faire en utilisant 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>
Production:
Essayons par un autre exemple, supposons que nous ayons un objet calculatrice comme ci-dessous-
<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>
Eh bien, cela fonctionne comme un charme, et si nous réaffectons accidentellement la valeur de l'objet calculatrice.
<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>
oui vous vous retrouverez avec une TypeError: calculator.mul n'est pas une fonction iffe.html
Mais avec l'aide de l'IFFE, nous pouvons créer une portée privée où nous pouvons créer une autre calculatrice de nom de variable et l'utiliser;
<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>
Je pense que les 2 jeux de parenthèses le rendent un peu déroutant mais j'ai vu une autre utilisation dans l'exemple de Google, ils ont utilisé quelque chose de similaire, j'espère que cela vous aidera à mieux comprendre:
var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);
donc si windows.app
n'est pas défini, alors window.app = {}
est immédiatement exécuté, donc window.app
est affecté avec {}
pendant l'évaluation de la condition, donc le résultat est à la fois app
et window.app
devient maintenant {}
, donc la sortie de la console est:
Object {}
Object {}
Normalement, le code JavaScript a une portée globale dans l'application. Lorsque nous y déclarons une variable globale, il est possible d'utiliser la même variable en double dans une autre zone du développement à d'autres fins. En raison de cette duplication, il peut se produire une erreur. Ainsi, nous pouvons éviter ces variables globales en utilisant l'expression de fonction immédiatement invoquée, cette expression est une expression auto- exécutable .
Deux façons de créer l' IIFE
(function () {
"use strict";
var app = angular.module("myModule", []);
}());
OU
(function () {
"use strict";
var app = angular.module("myModule", []);
})();
Dans l'extrait de code ci-dessus, « var app » est désormais une variable locale.