【JavaScript ES 6関数式プログラミング入門経典】読書ノート(第四章)

5447 ワード

第四章閉鎖と高次関数
4.1閉包を理解する
簡単に言えば、クローズドは内部関数であり、他の関数の内部にある関数です.
function outer() {
  function inner() {
  }
}
これはクローズドであり、関数innerはクローズド関数として知られています.このような強力な理由は、ロールドメインチェーン(またはロールドメイン階層)へのアクセスにあります.閉ループには3つのアクセス可能なスコープがあります.
  • .自身が宣言した変数
  • function outer() {
      function inner() {
        let a = 5;
        console.log(a)
      }
      inner() //   inner  
    }
    
    // tips: inner   outer          
    
    inner関数が呼び出されたとき、コンソールは5を返します.なぜなら、クローズド関数は内部宣言のすべての変数にアクセスできるからです.
  • .グローバル変数へのアクセスは、上のコードセグメントを
  • に変更します.
    let global = "global"
    function outer() {
      function inner() {
        let a = 5
        console.log(global)
      }
      inner() //   inner  
    }
    
    現在inner関数が実行された後、変数globalをプリントアウトします.そうすると、クローズドはグローバル変数にアクセスできます.
  • .外部関数変数へのアクセスは、関数
  • を変更します.
    let global = "global"
    function outer() {
      let outer = "outer"
      function inner() {
        let a = 5
        console.log(outer)
      }
      inner() //   inner  
    }
    
    inner関数が実行されると変数outerが印刷され、合理的に見えるが、非常に重要なクローズド属性である.クローズドは、外部関数の変数にアクセスできます.ここでは、外部関数の意味は、小包のクローズド関数の関数です.
    クローズドは、外部関数のパラメータにアクセスすることができます.例えば、アウト関数にパラメータを追加し、inner関数にアクセスを試みると、このパラメータが入手できます.
    クローズドはもう一つの重要な概念があります.クローズドはその文脈を覚えられます.
    var fn = (arg) => {
      let outer = "Visible"
      let innerFn = () => {
        console.log(outer)
        console.log(arg)
      }
      return innerFn
    }
    
    var closureFn = fn(5)
    closureFn()
    =>Visible
    =>5
    
    解析1.var closureFn = fn(5)、ここでfnはパラメータ5によって呼び出され、innerFnに戻りました.2.innerFnが戻ったとき、javascript実行エンジンはinner Fnを一つのクローズドと見なし、それに応じて設定されたスコープクローズドは3つのレベルで機能します.この3つのレベル(arg、outer値はinnerの役割領域階層に設定されます.Fnerは、Fner設定されます.)は、Fnerに戻ってきます.このようにclosureFnは、フィールドチェーンを介して呼び出されたときに、arg、outer値を覚えています.3.最終的にclosureFnを呼び出すと、その文脈(作用領域、つまりouterとarg)を覚えているので、consolone.logの呼び出しが正しい結果を印刷することができます.
    前の章のsortBy関数を振り返ってみます.
    const sortBy = (property) => {
      return (a, b) => {
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0
        return result
      }
    }
    
    sortBy関数は、2つのパラメータを受け入れる新しい関数(a, b) => { /* */ }のクローズドバック関数の範囲sortBy関数のパラメータpropertyを返します.このとき、propertyパラメータは一つの値に置き換えられます.したがって、バック関数は、バック関数がそのコンテキストにおいてpropertyの値を保持するので、バック関数が適切で必要なときにはリターン値を使用するコンテキストproperty = "passedValue"を介して、コンテキストをそのライフサイクルにおいて保持するであろう.
    4.2実際の高次関数
  • tap関数
  • const tap = (value) =>
      (fn) => (
        typeof(fn) === 'function' && fn(value),
        console.log(value)
      )
    // tap      value,       value     ,       。
    
    javascriptでは、2つのパラメータを実行し、2つの表式の結果、つまりexp 2を返すという意味です.
    tap関数(a, b) => { /* */ }=>value is fun=>funを実行しますが、この関数はどのような用途がありますか?もしサーバからの配列を遍歴して、データが間違っていることを発見したら、調整したいです.配列内に何が含まれているかを見てみて、どうすればいいですか?命令式を捨てる方法は、関数である方法で見られます.これはtap関数を使っています.このシーンに対しては、このようにしてもいいです.
    forEach([1, 2, 3], (a) =>
      tap(a)(()=>{
        console.log(a)
      })
    )
    
  • unary関数arrayプロトタイプは、標準的な方法をmapと呼び、mapは前に定義されたforEach関数と非常に似た関数であり、唯一の違いは、mapがコールバック関数の結果を返したことである.一つの配列を倍にして結果を得るためには、map関数を使用して、[1,2,3].map((a)=>{return a*)=>[1,4,9]ここでmapは、3つのパラメータで関数を呼び出します.可能であれば、関数は、着信したパーを数字に変換する.ParseIntをmap関数に送ると、mapはindexの値をパーrseIntのradixパラメータに送る.
  • ['1', '2', '3'].map(parseInt)
    => [1, NaN, NaN]
    
                ,     parseInt                   。
     unary      ,                 ,                  ,  :
    const unary = (fn) =>
      fn.length === 1
        ? fn
        : (arg) => fn(arg)
    
    入ってきたfnに長さ1のパラメータリストがあるかどうかを確認します.(length属性で調べられます.)あれば何もしません.いいえ、新しい関数を返します.一つのパラメータargだけを受信して、fnを呼び出して、上記の問題を再実行します.ここでunary関数は新しい関数(parseIntのクローン)を返します.パラメータは一つしか受信していません.このようにmap関数が入ってきたindex、arrパラメータはプログラムに影響を与えません.
    binaryのような関数もあります.それらは関数を変換して、対応するパラメータを受け入れさせます.
  • Once関数は一回だけ与えられた関数を実行します.例えば一回の第三者ライブラリを設定するか、一回の支払設定を初期化したいです.
  • const once = (fn) => {
      let done = false
      return function () {
        return done ? undefined : (done =true), fn.apply(this, arguments)
      }
    }
    
    一つのパラメータfnを受け取り、結果はそのアプリを呼び出して返します.done変数を宣言しました.初期値はfalseで、戻ってきた関数はそのクローズドロール領域をカバーするため、戻ってきた関数はdoneにアクセスして、trueであるかどうかを確認します.undefinedに戻ります.そうでないと、doneをtrueに設定します.必要なパラメータでfnを呼び出します.
    アプリ関数は、関数のコンテキストを設定し、与えられた関数のパラメータを伝達することができます.
    var doPayment = once(() => {
      console.log("Payment is done")
    })
    doPayment()
    => Payment is done
    doPayment()
    => undefined
    
  • memoized関数は、factoriaという純粋な関数があると仮定して、与えられた数値の階乗
  • を計算します.
    var factorial = (n) => {
      if (n === 0) {
        return 1
      }
      //   
      return n*facotrial(n-1)
    }
    
    この関数はパラメータのみに依存して実行します.他は必要ありません.前の計算結果を再利用できない制限があります.memoized関数はその計算結果を覚えられます.
    const memoized = (fn) => {
      const lookupTable = {}
      return (arg) => lookupTable[arg] || (lookupTable[arg] = fn(arg))
    }
    
    lookuppTableの局所変数を宣言します.戻り関数の閉込めコンテキストでは、戻り関数はパラメータを受け取り、lookuble内にあるかどうかを確認します.そうであれば、対応する値を返します.そうでなければ、新しい入力をkey、fnの結果をvalueとして、lookubleオブジェクトを更新します(tap("fun")((it) => console.log("value is ", it))).今は上のfactoralをmemoized関数で書き換えます.
    let fastFactorial = memoized((n) => {
      if (n === 0) return 1
      //   
      return n *fastFactorial(n-1)
    })
    
      fastFactorial
    fastFactorial(5)
    => 120
    
    同じ方式で運行していますが、以前よりずっと速くて、fastFactorialを運行する時に、lookubleの対象を検査します.
    第三章住所を添付します.高次関数第二章住所:JavaScript関数基礎第一章住所:関数プログラミング紹介