ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptの匿名関数、名前付き関数、即時実行関数について詳しく解説 IIFE

JavaScriptの匿名関数、名前付き関数、即時実行関数について詳しく解説 IIFE

黄舟
黄舟オリジナル
2017-02-28 15:06:452689ブラウズ

JavaScript の関数スコープは、変数と関数を「隠す」ために存在します

最小特権の原則に沿って
同時に、別の利点は、同じ名前の識別子との競合を回避できることです
今日は主にこれについて話します 関数をすぐに実行します
その前に、匿名関数と名前付き関数を確認してください

匿名関数と名前付き関数

匿名でも名前付きでも、それらはすべて関数式です
関数宣言には名前が必要です。それ以外の場合は、エラーが発生します。報告されます

function foo(){ //函数声明
    //...}

ここでイースターエッグについて説明します。私が記事を書くときにいつもいくつかのサンプルコードを使用するのが好きかもしれません
fn、func、demo、foo、bar、foobar などの単語
fn と func は function の略称です
デモとは、「サンプル」という言葉の略語です
foo、bar、foobar は技術書やコンピューター関連の文献でよく見かけます
Foo は、「めちゃくちゃ」を意味する、fuck-up の略語である fu の変形です
bar は「beyond all reconception」、平たく言えば「認識できない、めちゃくちゃ」という意味です
。 これらは、Xiao Ming Xiao Kong、A、B、B、Ding、Zhang San、Li Si に相当する単なるプレースホルダーです。

関数式には名前を付けることも、名前を付けないこともできます

var foo = function(){...};
console.log(foo.name); //foo
var bar = function foobar(){...};//不要这么写
console.log(bar.name); //foobar

2 番目の書き方が変わっただけです 関数
のname属性はそれ以外は役に立たないので、このように書くのはやめましょう

また、最も一般的な使用法は、関数式をコールバックパラメータとして使用することです
例えば、タイマー内で

setTimeout(function(){
    //...},1000);

ここで匿名関数式を書きます
シンプルで使いにくいです
しかし、いくつかの欠点があります

  • トレーススタックに関数名がないため、デバッグが困難です

  • 自分自身を参照する必要がある場合は、使用できるのは argument.callee のみです (ES5 厳密モードでは無効になっています)

  • 関数の読みやすさと理解しやすさが低下します

イベントのバインドを解除するときは、関数名も必要です (イベントが直接バインドされていない場合) onclick など)
それでは
関数式に名前を付けるのがベストプラクティスであり良い習慣です

setTimeout(function timerHandler(){
    //...},1000);

即時実行関数の一般的な使い方

即時実行関数、私はその呼び方に慣れています
selfとも呼ばれます-実行関数、自動実行関数など
より標準的なものです
即時実行関数式です
関数式ですので、表現に注意してください

構文ではありません
しかし、誰もがそれを使用しており、次のような場合に使用できることがわかりましたこのように
それで広まり、今に至ります
その名前が示すように、これは実行フロー操作ですこの関数はすぐに実行されます
コミュニティはそれに対する用語を定義しています:IIFE(Immediately Invoked Function Expression)

私たちの一般的な使用法は次のとおりです:

(function(){
    //...}());
(function(){
    //...})();

IIFE を使用するときは、通常、匿名関数式を使用します
もちろん、名前を追加するのは良いことであり、名前付き関数式の利点もあります
2 つの使用法は完全に同等です。どちらを使用するかを決定します
しかし、私は括弧を外側に書くことを好みます。そのほうが快適です
そしてそれは見栄えが良いです多くのマスターは私と同じです

即時実行関数の高度な使用法

もう少し高度な使用法は、パラメータを即時実行関数
例えば、一般的に window を渡します

var a = '全局';
(function IIFE(global){    var a = '局部';    console.log(a);// "局部"
    console.log(global.a);// "全局"})(window);

window を渡すメリットは何ですか?
スコープの観点からの分析
(私が書いたスコープをご覧ください -> ポータル)
グローバルオブジェクトの参照はローカル環境にキャッシュされます
このようにして、グローバルオブジェクトにアクセスすることなく、より高速にアクセスできますトップレベルにジャンプします
この小さな最適化は焦点ではありません
重要なポイントはコードを圧縮するときに最適化できます
おそらく上記のコード圧縮ツールはこのように圧縮できるでしょう

すごい

コードが非常に大きい場合は、ドンこの最適化を過小評価しないでください

さて、実行関数の使用法には別のバリエーションもあります

IIFE、あなたも見たことがあるでしょう

var a = '全局';
(function IIFE(g){    var a = '局部';    console.log(a);// "局部"
    console.log(g.a);// "全局"})(window);

実行される関数をパラメータに入れるこのモードは非常に面倒に見えます
しかし、それは広く使用されており、 jQueryなどのフレームワークの全体的なアーキテクチャもこれに似ています
これも非常に似ています

慣れれば従来の使い方よりも理解しやすいと感じるでしょう


全体的な関数式は、の後半で定義されていますIIFE、そしてIIFEの最初の部分にパラメータとして渡されます

次に関数が呼び出され、パラメータとしてウィンドウを渡します

即時実行関数の理解

なぜ即時実行関数は自動的に実行できるのでしょうか?

(function IIFE(demo){
    demo(window);})(function demo(global){
    //...
});
function(){}()なぜ
このように書けないのか
これは関数宣言であり、関数宣言は実行できないからです実行できるのは式だけです

(function(){
    //...})();

これは式なので実行できます
とはデモが取得するのは関数の戻り値です

式が実行できるので、以下のメソッドもすぐに実行できます

var demo = function(){
    console.log(1);// 1
    return 123;
}();
console.log(demo);// 123

カンマも関数式にしてすぐに実行できることがわかります
ただし、次のように書いてはいけませんこれ
関数に戻り値がある場合、予期せぬ副作用が発生する可能性があり

、可読性も良くありません

概要
  • 関数の宣言には名前が必要です🎜
  • 名前付き関数式はベストプラクティスです

  • 関数式の使用法を即時実行します: (function(){}()); (function(){})();

  • ウィンドウパラメーターを渡す関数を即時実行します スコープチェーン内のウィンドウ速度を最適化します。これはコードの圧縮に有益です

  • 式のみ実行可能

上記は、JavaScript の匿名関数、名前付き関数、および即時実行関数 IIFE の詳細な説明です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。