Maison > Article > interface Web > Compréhension approfondie des expressions de fonction JavaScript immédiatement invoquées (IIFE)
Fonction d'appel immédiat
Répertoire
Écrivez à la fin
(Recommandation d'apprentissage gratuite : tutoriel vidéo javascript)
1. Comprendre l'expression de. fonction d'appel immédiat
Avant d'en savoir plus, parlons du terme « auto-exécution ». Le terme désignant cette fonction dans cet article n'est peut-être pas tout à fait correct. Tout le monde en a une compréhension différente. Nous sommes ici. , utilisez 立即调用
~
pour l'appeler immédiatement :
创建就立即执行
. JavaScript 函数
qui sera exécuté immédiatement lorsqu'il sera défini. (function (x) { console.log('x + x = ', x + x);})(5) // x + x = 10
Il s'agit d'un modèle de conception appelé 自执行匿名函数
, qui se compose principalement de deux parties :
()
Un anonyme fonction qui a une portée lexicale indépendante. Cela empêche non seulement l'accès externe aux variables de cet IIFE, mais ne pollue pas non plus la portée globale. ()
pour créer une expression de fonction d'exécution immédiate, et le moteur JavaScript exécutera la fonction directement. Lorsque vous déclarez une fonction, peut-elle être exécutée immédiatement en ajoutant des parenthèses à la fin ?
var foo = function(){ console.log('余光');}(); // 余光 成功了! // ...是不是意味着后面加个括弧都可以自动执行?function(){ console.log(''余光);}(); // Uncaught SyntaxError: Function statements require a function name// 什么?还需要一个函数名?不是叫 自执行匿名函数吗?// 我加上了函数名function foo(){ console.log('余光');}(); // Uncaught SyntaxError: Unexpected token ')'
Évidemment, les deuxième et troisième éléments de l'exemple signalent des erreurs, et le contenu de l'erreur est différent, alors où se produit le problème ?
2. Une erreur est signalée lors de l'appel immédiat d'une expression de fonction ?
Parfois, après avoir défini une fonction, nous appelons la fonction immédiatement. Dans ce cas, nous ne pouvons pas ajouter de parenthèses directement après la définition de la fonction, ce qui provoquera une erreur de syntaxe. La raison de l'erreur de syntaxe est que le mot-clé function
peut être utilisé soit comme une instruction, soit comme une expression, comme ce qui suit :
//语句function fn() {};//表达式var fn = function (){};
Afin d'éviter les ambiguïtés d'analyse, le moteur JS stipule que si la fonction apparaît dans Le début d'une ligne est toujours analysé en une instruction. Par conséquent, une fois que le moteur JS voit que le mot-clé function se trouve au début de la ligne, il pense que ce paragraphe est une définition de fonction et ne doit pas être précédé de 括号结尾
. Selon lui, 括号
est simplement un opérateur de regroupement. .
// 下面这个function在语法上是没问题的,但是依然只是一个语句// 加上括号()以后依然会报错,因为分组操作符需要包含表达式 function foo(){ /* code */ }(); // SyntaxError: Unexpected token ) // 但是如果你在括弧()里传入一个表达式,将不会有异常抛出// 但是foo函数依然不会执行function foo(){ /* code */ }( 1 ); // 因为它完全等价于下面这个代码,一个function声明后面,又声明了一个毫无关系的表达式: function foo(){ /* code */ } ( 1 );
3. La posture correcte d'utilisation de l'appel de fonction immédiat
Pour résoudre le problème ci-dessus , c'est très simple .
Nous n'avons besoin que d'utiliser 大括弧
pour inclure tout le code. Parce que JavaScript ne peut pas contenir d'instructions dans 括弧()
, donc à ce stade, lorsque l'analyseur analyse le mot-clé de fonction, le code correspondant sera analysé. expressions de fonction au lieu de déclarations de fonction.
// 下面2个括弧()都会立即执行(function () { /* code */ } ()); // 推荐使用这个(function () { /* code */ })(); // 但是这个也是可以用的
// 由于括弧()和JS的&&,异或,逗号等操作符是在函数表达式和函数声明上消除歧义的// 所以一旦解析器知道其中一个已经是表达式了,其它的也都默认为表达式了var i = function() { console.log('余光')}(); // 余光true && function() { console.log('余光')}(); // 余光0, function() { console.log('余光') }(); // 余光
// 如果你不在意返回值,或者不怕难以阅读// 你甚至可以在function前面加一元操作符号//转boolvar res1 = !function () { console.log('余光');}()console.log('res1:', res1); // 余光 true// 转数字var res2 = +function () { console.log('余光');}()console.log('res2:', res2); // 余光 NaN// 按位非var res3 = ~function () { console.log('余光');}()console.log('res3:', res3); // 余光 NaN
Il existe une autre situation où les mots-clés new et void sont utilisés, mais ce n'est pas très courant.
void function() { console.log('余光');}();new function() { console.log('余光');}();
4. Scénarios d'utilisation courants
La fonction la plus courante d'IIFE est la portée d'isolation, qui était native de JS avant ES6. Il n'y a pas de concept de portée au niveau du bloc, donc la portée de la fonction est nécessaire pour la simuler.
Exemple :
var currentTime = (function () { var time = new Date(); var year = time.getFullYear() var month = time.getMonth()+1; var date = time.getDate(); var hour = time.getHours(); var min = time.getMinutes(); return year + '-' + month + '-' + date + ' ' + hour + ':' + min;})()
Vous pouvez toujours déclarer des variables portant le même nom ailleurs~
Les événements DOM sont ajoutés pour être compatibles avec navigateurs modernes Avec le navigateur IE, nous devons porter un jugement sur l'environnement du navigateur :
var addEvent = (function(){ if(window.addEventListener) { return function(type, el, fn) { el.addEventListener(type, fn, false); } } else if(window.attachEvent) { return function(type, el, fn) { el.attachEvent('on' + type, fn); } }})();
Ici, je ne donnerai qu'un exemple pour mon prochain article—— " Fermetures en JavaScript" Jetons un coup d'oeil
var elems = document.getElementsByTagName('a');for (var i = 0; i <h5>Remarque</h5><p>Lorsque la fonction devient une expression de fonction qui est exécutée immédiatement, les variables de l'expression ne sont pas accessibles de l'extérieur. </p><pre class="brush:php;toolbar:false">(function () { var name = "Barry";})();// 无法从外部访问变量 namename // 抛出错误:"Uncaught ReferenceError: name is not defined"
Attribuez l'IIFE à une variable, non pas pour stocker l'IIFE lui-même, mais pour stocker le résultat renvoyé après l'exécution de l'IIFE.
var result = (function () { var name = "Barry"; return name; })(); // IIFE 执行后返回的结果:result; // "Barry"
Recommandations d'apprentissage gratuites associées : javascript(vidéo)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!