【JavaScript ES 6関数式プログラミング入門経典】読書ノート(第四章)
5447 ワード
第四章閉鎖と高次関数
4.1閉包を理解する
簡単に言えば、クローズドは内部関数であり、他の関数の内部にある関数です..自身が宣言した変数 .グローバル変数へのアクセスは、上のコードセグメントを に変更します..外部関数変数へのアクセスは、関数 を変更します.
クローズドは、外部関数のパラメータにアクセスすることができます.例えば、アウト関数にパラメータを追加し、inner関数にアクセスを試みると、このパラメータが入手できます.
クローズドはもう一つの重要な概念があります.クローズドはその文脈を覚えられます.
前の章のsortBy関数を振り返ってみます.
4.2実際の高次関数 tap関数
tap関数 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パラメータに送る.
binaryのような関数もあります.それらは関数を変換して、対応するパラメータを受け入れさせます. Once関数は一回だけ与えられた関数を実行します.例えば一回の第三者ライブラリを設定するか、一回の支払設定を初期化したいです.
アプリ関数は、関数のコンテキストを設定し、与えられた関数のパラメータを伝達することができます. memoized関数は、factoriaという純粋な関数があると仮定して、与えられた数値の階乗 を計算します.
第三章住所を添付します.高次関数第二章住所:JavaScript関数基礎第一章住所:関数プログラミング紹介
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実際の高次関数
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)
})
)
['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のような関数もあります.それらは関数を変換して、対応するパラメータを受け入れさせます.
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
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関数基礎第一章住所:関数プログラミング紹介