JavaScriptプログラミングの詳細(3)

4307 ワード

第三章関数
  • 関数は、JavaScriptに不可欠な構成部分
  • である.
  • 関数は、大規模なプログラムを構築するためのツールであり、反復的な動作を低減し、サブルーチンに名前を付け、個々のサブルーチンの動作を分離するために使用されてもよい.
  • 3.1定義関数
    関数の表現をキーワードfunctionで開始します.
    var fun = function (parameter1, parameter2, ...) {//      ,        
        //    ,        ,         ,           
        ...
        // return           ,          undefined
        return;
    }
    
    3.2パラメータとスコープ
  • 関数のパラメータ初期値は、関数使用者によって提供される.
  • 関数内部で作成された変数とパラメータは、関数間の相互干渉がないことを保証する関数の局所変数に属します.
  • 3.3ネストスコープ
  • は、関数内に他の関数を作成し、異なる程度の局所作用領域を生成することができる.
  • の任意の局所作用領域は、その部分作用領域を含む
  • にアクセスすることができる.
  • 関数の内部変数の視認性は、関数のコード内の位置に依存し、関数で定義されたコードブロックの中で、この関数はコードブロック内のすべての変数、すなわち関数上部のコードブロック内の変数と関数内部の変数にアクセスすることができます.このような変数を制御する方法をワードスコープと呼びます.
  • letキーワードの役割はvarと同じであるが、変数のスコープは関数の局所的なスコープではなくブロックのスコープである.
  • 3.4関数値
    関数と関数名の違い:関数は、function参照タイプと呼ばれる実例であるため、関数はオブジェクトです.オブジェクトはメモリに保存され、関数名はこのオブジェクトを指すポインタです.
    JavaScriptの関数は一等公民で、パラメータとして別の関数に入ることができます.また、関数の戻り値としてもいいし、値を再割り当てすることもできます.
    3.5記号宣言
    関数宣言はもっと簡潔な方法があります.
    function fun(parameter) {
        //todo
    }
    
  • 関数宣言は、一般的な上から下へのフロー制御ルールに従わない.
  • console.log('are you ok ?', ans());
    
    function ans() {
        return 'yeah, i\'m ok';
    }
    
  • は、関数が異なる環境で動作する挙動が一致することを保証するために、最外層の関数またはプログラムのスコープにおいて関数宣言を行うべきである.
  • 3.6コールスタック
    関数は、実行終了後に関数のコード位置に遷移する必要があるので、関数呼び出しのコンテキストをコンピュータが覚えておく必要があります.コンピュータがこのコンテキストを記憶する領域を と呼ぶ.
  • 関数が起動すると、現在のコンテキスト情報はスタックトップ
  • に格納されます.
  • 関数が戻ると、システムはスタックトップに記憶されているコンテキスト情報を削除し、この情報を使ってプログラムを実行し続ける.
  • //          ,           ,               ,  “     ”。
    function chicken() {
        return egg();
    }
    function egg() {
        return chicken();
    }
    console.log(chicken() + ' came first.');
    
    3.7オプションパラメータ
    JavaScriptは、伝達関数のパラメータ数に対しては、ほとんど制限がありません.多すぎるパラメータを渡すと、余分なパラメータが無視されます.もしあなたが伝達するパラメータが少なすぎると、漏れたパラメータはundefinedに割り当てられます.
    短所:あなたはたまたま関数に間違った数のパラメータを伝えたかもしれませんが、誰もあなたにこのエラーを教えてくれません.
    利点:この挙動を利用して、関数に任意のパラメータを受信させることができます.
    3.8クローズド
    関数が既に実行されている場合、これらの関数によって作成されたローカル変数はどのように処理されますか?
    function wrapValue(n) {
        var localVariable = n;
        return function { return localVariable; };
    }
    var wrap1 = wrapValue(1);
    var wrap2 = wrapValue(2);
    console.log(wrap1());
    // 1
    console.log(wrap2());
    // 2
    
    このコードは、局所変数が関数呼び出しごとに再作成され、異なる関数呼び出しが他の関数内の局所変数に影響を与えないことをよく実証しています.
    このような特定の局所変数のインスタンスを参照する機能をクローズドと呼ぶ.いくつかの局所変数を包装した関数はクローズドされています.クローズドの特性を利用して,変数のライフサイクル問題を心配する必要はなくなり,多くの高級な応用がそれに依存して実現される.
    function multiplier(factor) {
        return function(number) {
            return number * factor;
        }
    }
    
    var twice = multiplier(2);
    console.log(twice(5));
    //10
    
    キーワードfunctionを「凍結」コードとして扱い、函数値のモデルとして包装することができる.したがって、「return function(...){-}」というコードを見たとき、それを一つのハンドルとして理解することができ、その中のハンドルは一つのパッケージの計算コードを指す.
    3.9再帰
    関数は完全に自分で呼び出すことができます.スタックオーバーフローの問題を避けるだけでいいです.私たちは関数を自身の行動に呼び戻すことを再帰と呼びます.
    function power(base, exponent) {
        if (exponent == 0)
          return 1;
        else
          return base * power(base, exponent-1);
    }
    
    console.log(power(2, 3));
    // 8
    
    注意したいのは、標準的なJavaScript実装では、再帰的な書き方の関数の実行効率はサイクル・書き方の関数より約10倍遅くなります.どのように性能と優雅を評価するかは考慮に値する問題ですが、基本原則があります.
    いくつかの問題に対しては、再帰相はサイクルよりも問題を解決することができる.このような問題は通常、複数のブランチを実行して処理する必要があり、各ブランチはさらに多くの実行分岐を引き出す.
    3.10新しい関数を追加
    2つの一般的な関数の導入方法:
  • は、プログラムに複数の類似コードを見つける.
  • は新しい機能コードを書きます.いくつかのコードは一つの関数に含まれるべきだと思います.関数のコードを先に作成してから呼び出しの関数を具体的に実現することもできます.
  • 関数に名前をつける難しさは,パッケージの関数の用途が明確かどうかに依存する.
    3.11関数とその副作用
    関数は2つの種類に分けられます.1つのタイプの呼び出しで副作用が発生し、もう1つのタイプの場合は戻り値が発生します.もちろん、副作用と戻り値を同時に生成する関数も定義できます.
    副作用を直接発生させる関数よりも,戻り値を生成する関数が新しい環境に集積しやすくなる.しかし、副作用の助けの下で、一部の操作はより簡単で、より速く実現されます.そのため、演算速度を考慮して、時には純関数は好ましくない場合があります.
    3.12本章のまとめ
  • は、キーワードfunctionにとって、式として使用すると、関数値を作成することができる.これを文として使うと、宣言して関数を変数に与えることができます.
  • // Create a function value f
    var f = function(a) {
        console.log(a + 2);
    }
    
    // Declare g to be a function
    function g(a, b) {
        return a * b * 3.5;
    }
    
  • は、関数の意味を理解するためには、局所作用領域の概念を理解しなければならない.関数については、そのパラメータと内部宣言の変数は局所変数であり、関数を呼び出すたびにこれらの変数は再作成され、外部には見えない.関数のスコープ内で宣言された関数は,その外部関数の局所的なスコープにアクセスできる.
  • は、プログラム内のタスクを異なる関数に分割する方法が非常に有用であり、コードの読み取り可能性を高めるのに役立つ.