JavaScriptのコリ化
5994 ワード
概要
カリングは、複数のパラメータを受信する関数を単一のパラメータ(最初の関数の最初のパラメータ)を受け入れる関数に変え、残りのパラメータを受け入れて結果を返す新しい関数の技術です.
コア思想:マルチパラメータが入ってきた関数を単一パラメータ(または一部パラメータ)関数に分解し、内部から次の単一パラメータ(または一部パラメータ)関数を呼び出して、残りのパラメータを順次処理します.
Styan Stefanov--「JavaScript Pattern」の著者によると、コリメートとは関数を理解して処理する部分的なアプリケーションのことです.
JavaScriptでCurryingを実現
関数の一部だけに渡すパラメータを実現するために呼び出し、残りのパラメータを処理するための関数を返します.この文で説明されている特徴.まず、加算関数
しかし、
Currying応用シーン
パラメータ多重化
不変のパラメータを固定し,パラメータ多重を実現することはCurryingの主な用途の一つである.
ケース1
上記の
ケース2
対象の種類を判断する.例えば、以下の例:
実行を遅らせる
遅延実行もCurryingの重要な使用シーンであり、同様に
ダタ属性で
カリングは、複数のパラメータを受信する関数を単一のパラメータ(最初の関数の最初のパラメータ)を受け入れる関数に変え、残りのパラメータを受け入れて結果を返す新しい関数の技術です.
コア思想:マルチパラメータが入ってきた関数を単一パラメータ(または一部パラメータ)関数に分解し、内部から次の単一パラメータ(または一部パラメータ)関数を呼び出して、残りのパラメータを順次処理します.
Styan Stefanov--「JavaScript Pattern」の著者によると、コリメートとは関数を理解して処理する部分的なアプリケーションのことです.
JavaScriptでCurryingを実現
関数の一部だけに渡すパラメータを実現するために呼び出し、残りのパラメータを処理するための関数を返します.この文で説明されている特徴.まず、加算関数
add
を実現します.function add(x, y) {
return x + y
}
私たちは今Curryingのadd
関数を実装し、この関数はcurriedAdd
と命名されると、上記の定義に従って、curriedAdd
は以下の条件を満たす必要があります.curriedAdd(1)(3) === 4 // true
var increment = curriedAdd(1)
increment(2) === 3 // true
var addTen = curriedAdd(10)
addTen(2) === 12 // true
以上の条件を満たすcurriedAdd
関数は、以下のコードで実装されてもよい.function curriedAdd(x) {
return function(y) {
return x + y
}
}
もちろん以上の実装にはいくつかの問題があります.一般的ではなく、関数が人によって変更される方法でCurrying化を実現したくないです.しかし、
curriedAdd
の実装は、Curryingの基礎となるCurrrying遅延求値を実現する特性がJavaScript
における作用領域を使用する必要があることを示しており、より分かりやすく説明するには、前回送信されたパラメータを保存するために作用領域(すなわち、クローズド)を使用する必要がある.curriedAdd
を抽象化すると、次のような関数currying
が得られる.function currying (fn, ...args1) {
return function (...args2) {
return fn(...arg1, ...arg2)
}
}
var increment = currying(add, 1)
increment(2) === 3 // true
var addTen = currying(add, 10)
addTen(2) === 12 // true
この実装では、currying
関数の戻り値は、実際には残りのパラメータを受け取り、計算値をすぐに返す関数である.つまり、その戻り値はCurryingに自動的に返されません.したがって、currying
を再帰的に返した関数も自動的にCurryingとすることができる.function currying(fn, ...args) {
if (args.length >= fn.length) {
return fn(...args)
}
return function (...args2) {
return currying(fn, ...args, ...args2)
}
}
以上の関数は簡単ですが、Curryingの核心思想はすでに実現されました.JavaScript
においてよく使用されるライブラリLodash
におけるcurry
の方法は、コア思想と以上の違いがあまりない.複数回受信されたパラメータの総数と関数が定義されたときのイメージの数を比較し、受信されたパラメータの数がCurrying関数のイメージの数以上である場合、実行結果に戻り、そうでない場合は引き続きパラメータを受け入れる関数を返す.Currying応用シーン
パラメータ多重化
不変のパラメータを固定し,パラメータ多重を実現することはCurryingの主な用途の一つである.
ケース1
上記の
increment
、addTen
のパラメータ多重の一例.add
方法に対して、最初のパラメータを10と固定すると、この方法はアキュムレータ10を受け入れる方法になる.ケース2
対象の種類を判断する.例えば、以下の例:
function isArray (obj) {
return Object.prototype.toString.call(obk) === '[object Array]'
}
function isNumber (obj) {
return Object.prototype.toString.call(obj) === '[object Number]'
}
function isString (obj) {
return Object.prototype.toString.call(obj) === '[object String]'
}
// Test
isArray([1, 2, 3]) // true
isNumber(123) // true
isString('123') // true
しかしながら、上記のスキームにはそれぞれのタイプが一つの方法を定義する必要があります.ここではbind
を使用して拡張することができます.利点は改造後のtoStr
を直接使用することができます.const toStr = Function.prototype.call.bind(Object.prototype.toString)
//
[1, 2, 3].toString() // "1,2,3"
'123'.toString() // "123"
123.toString() // SyntaxError: Invalid or unexpected token
Object(123).toString() // "123"
// toStr
toStr([1, 2, 3]) // "[object Array]"
toStr('123') // "[object String]"
toStr(123) // "[object Number]"
toStr(Object(123)) // "[object Number]"
上記の例は、まずFunction.prototype.call
関数を使用して、this
値を指定した後、.bind
は新しい関数を返し、常にObject.prototype.toString
を着信パラメータに設定します.実行を遅らせる
遅延実行もCurryingの重要な使用シーンであり、同様に
Object.prototype.toString.call()
およびbind
も同様の機能を実現することができる.フロントエンド開発では、一般的なシーンは、ラベルバインディング
であり、バインディングの方法としてパラメータを伝達することを考慮している.下記にいくつかのよくある方法を出して、優劣を比較します.ダタ属性で
通过data
属性本质只能传递字符串的数据,如果需要传递复杂对象,只能通过 JSON.stringify(data)
来传递满足JSON
对象格式的数据,但对更加复杂的对象无法支持。(虽然大多数时候也无需传递复杂对象)
通过bind方法
bind
方法和以上实现的currying
,在功能上有极大的相似,在实现上也几乎差不多。可能唯一的不同就是bind
方法需要强制绑定context
,也就是bind
的第一个参数会作为原函数运行时的this
指向。而currying
不需要此参数。所以使用currying
或者bind
只是一个取舍问题。
箭头函数
handleOnClick(data))} />
, bind
context
。
currying
jsPerf
, :
> bind
> currying
> trueCurrying
。
currying
bind
, , , bind
, 。
Currying
1. Currying
, ,bind
,
, Curring
。
2. Currying
Currying
, , 。
JavaScript
, Haskell
,JavaScript
Currying
, 。
JavaScript
, Currying
JavaScript
。
-
Currying
JavaScript
, , 。
-
Currying
。
-
Currying
, 。 , Currying
。
+ , :https://cloud.tencent.com/dev...