ホームページ > 記事 > ウェブフロントエンド > JavaScript の即時呼び出し関数式 (IIFE) についての深い理解
関数をすぐに呼び出す
##ディレクトリ
(無料学習の推奨事項: javascript ビデオ チュートリアル)
1. 当面の課題を理解するcall 関数式
1.1 マインド マップ 1.2 Immediate Call とは何ですか? これについて詳しく学ぶ前に、「自己実行」という用語について話しましょう。この記事でこの機能を表す用語は完全に正しいとは限りません。それに対する理解は人それぞれ異なります。私たちはここにいます はすぐに呼び出すために使用されます ~
は、定義されるとすぐに実行される
(function (x) { console.log('x + x = ', x + x);})(5) // x + x = 10
と呼ばれるデザイン パターンで、主に 2 つの部分で構成されます。
2 番目の部分では、再び
var foo = function(){
console.log('余光');}(); // 余光 成功了!
// ...是不是意味着后面加个括弧都可以自动执行?function(){
console.log(''余光);}(); // Uncaught SyntaxError: Function statements require a function name// 什么?还需要一个函数名?不是叫 自执行匿名函数吗?// 我加上了函数名function foo(){
console.log('余光');}(); // Uncaught SyntaxError: Unexpected token ')'
明らかに、例の 2 番目と 3 番目の項目はエラーを報告しますが、エラーの内容は異なります。では、どこで問題が発生しているのでしょうか?
関数を定義した後、すぐに関数を呼び出すことがありますが、この場合、関数定義の直後に括弧を追加することはできないため、構文エラーが発生します。構文エラーの理由は、キーワード
function が次のようなステートメントまたは式として使用できるためです。 <pre class="brush:php;toolbar:false">//语句function fn() {};//表达式var fn = function (){};</pre>
解析のあいまいさを避けるために、JS エンジンは関数が行の先頭にある場合、関数は常にステートメントに解析されると規定されています。したがって、JS エンジンは、行の先頭にある function キーワードを認識すると、この段落は関数定義であり、
で終わるべきではないと判断します。は単なるグループ化演算子です。 <pre class="brush:php;toolbar:false">// 下面这个function在语法上是没问题的,但是依然只是一个语句// 加上括号()以后依然会报错,因为分组操作符需要包含表达式
function foo(){ /* code */ }(); // SyntaxError: Unexpected token )
// 但是如果你在括弧()里传入一个表达式,将不会有异常抛出// 但是foo函数依然不会执行function foo(){ /* code */ }( 1 );
// 因为它完全等价于下面这个代码,一个function声明后面,又声明了一个毫无关系的表达式: function foo(){ /* code */ }
( 1 );</pre>
3. イミディエート関数呼び出しを使用する正しい姿勢
上記の問題を解決するにはとてもシンプルです。
bracesを使用してすべてのコードを囲むだけで済みます。JavaScript では
brackets() にステートメントを含めることができないため、この時点でパーサーが解析するときに、 function キーワードを指定すると、対応するコードが関数宣言ではなく関数式に解析されます。 3.1 一般的な使用姿勢
<pre class="brush:php;toolbar:false">// 下面2个括弧()都会立即执行(function () { /* code */ } ()); // 推荐使用这个(function () { /* code */ })(); // 但是这个也是可以用的</pre>
3.2 一般的でない使用姿勢 (1)
// 由于括弧()和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
void function() { console.log('余光');}();new function() { console.log('余光');}();4. 一般的な使用シナリオ
4.1 分離スコープIIFE の最も一般的な機能は分離スコープであり、これは ES6 より前の JS にネイティブでした。ブロックレベルのスコープの概念がないため、それをシミュレートするには関数スコープが必要です。
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;})()
他の場所でも同じ名前の変数を宣言できます~
4.2 遅延関数
互換性のために DOM イベントが追加されています最新のブラウザを使用する場合 IE ブラウザを使用する場合は、ブラウザ環境を判断する必要があります。
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); } }})();
ここでは、次回の記事のための例のみを示します。 「JavaScriptのクロージャ」 見てみましょう
var elems = document.getElementsByTagName('a');for (var i = 0; i <h5>Note</h5><p>関数が即時実行される関数式になると、式内の変数に外部からアクセスできなくなります。 </p><pre class="brush:php;toolbar:false">(function () { var name = "Barry";})();// 无法从外部访问变量 namename // 抛出错误:"Uncaught ReferenceError: name is not defined"
var result = (function () { var name = "Barry"; return name; })(); // IIFE 执行后返回的结果:result; // "Barry"
関連する無料学習の推奨事項:
javascript(ビデオ)
以上がJavaScript の即時呼び出し関数式 (IIFE) についての深い理解の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。