柯里化の先端についての面接問題
7566 ワード
JSタイプの転換とコリゼーション
関数を実装すると、演算結果は次のような予想される結果を満たすことができます.
add(1)(2)/3 add(1,2,3)(10)/16 add(1)(2)(3)(4)(5)/15
まず自分の答えを書きます.関数の暗黙的な変換JavaScriptは弱いタイプの言語として、その暗黙的な変換は非常に柔軟で面白い.暗黙的な変換について深く理解していない場合、
注:
call/appy を利用します.浅い柯里化から始まるテーマは明らかで、計算結果はすべてのパラメータの和であり、add方法は毎回実行すると、必ず同じ関数を返して、残りのパラメータを計算し続けます.一番簡単な例から一歩一歩解決策を探すことができます.
カリー化(英語:Currying)は、部分求値とも呼ばれ、複数のパラメータを受け取る関数を単一のパラメータ(最初の関数の最初のパラメータ)を受け入れる関数に変換し、新しい関数を返す技術であり、新しい関数は残りのパラメータを受け取り、演算結果を返します. は単一パラメータを受信し、多くの情報を携帯するため、コールバック関数の理由で解決されることが多い. は、部分パラメータをコールバック関数などによって関数に入力する .は、着信したいすべてのパラメータ を処理するための新しい関数を返します.
上記の例では、add(1,2,3,4)をadd(1)(2)(3)(4)に変換することができる.これは部分的な価値観です.毎回入ってくるパラメータは全部私たちが伝えたいパラメータの中の一部です.
関数を実装すると、演算結果は次のような予想される結果を満たすことができます.
add(1)(2)/3 add(1,2,3)(10)/16 add(1)(2)(3)(4)(5)/15
まず自分の答えを書きます.
function add(){
// ,
var args = [].slice.call(arguments);
// , _args
var fn = function(){
var fn_args = [].slice.call(arguments);
return add.apply(null, args.concat(fn_args));
}
// , ,
fn.toString = function(){
return args.reduce(function(acc, prev){
return acc + prev;
})
}
return fn;
}
見終わったら雲霧の中で、copyに及ばないと思いますか?次に、みんなと一緒にこの問題の知識点を整理します.4 + true = 5
のようないくつかの演算の結果に困惑することがあります.まず簡単な思考問題をください.function fn(){
return 20;
}
console.log(fn + 10); // ?
を少し修正して、出力結果はどうなりますか?function fn() {
return 20;
}
fn.toString = function() {
return 10;
}
console.log(fn + 10); // ?
はまた修正を続けてもいいです.function fn() {
return 20;
}
fn.toString = function() {
return 10;
}
fn.valueOf = function() {
return 5;
}
console.log(fn + 10); // ?
以上の出力結果は、それぞれfunction fn() {
return 20;
}10
20
15
であり、consolone.logを使用するか、または演算する場合、暗黙的な変換が発生する可能性がある.上の3つの例から関数の陰的遷移に関するいくつかの結論を得ることができた.toString
とvalueOf
を再定義していない場合、関数の暗黙的変換は、デフォルトのtoString
方法を呼び出し、関数の定義内容を文字列として返します.toString/vauleOf
方法を主導的に定義した場合、暗黙的に変換された戻り結果は私たち自身で制御されます.注:
valueOf
の優先度はtoString
より高いです.add(1)(2); // 3
function add(a){
return function(b){
return a + b;
}
}
add(1)(2)(3); // 6
function add(a){
return function(b){
return function(c){
return a + b + c;
}
}
}
上のパッケージは私たちが望む結果と似ているように見えますが、パラメータの使用は死ぬほど制限されていますので、私たちが欲しい最終結果ではなく、共通のパッケージが必要です.どうすればいいですか?上の2つの例をまとめます.実は私たちはクローズドの特性を利用して、最後に戻った関数に全てのパラメータを集めて計算し、結果を返します.したがって、パッケージ化の際には、主な目的はパラメータをまとめて計算することです.今振り返って上の答えを見てみます.そんなにぼんやりしていませんか?function add(){
// ,
var args = [].slice.call(arguments);
// ,
// _args
var fn = function(){
var fn_args = [].slice.call(arguments);
return add.apply(null, args.concat(fn_args));
}
// ,
// ,
fn.toString = function(){
return args.reduce(function(acc, prev){
return acc + prev;
})
}
return fn;
}
ではここからコリック化という定理を引き出します.カリー化(英語:Currying)は、部分求値とも呼ばれ、複数のパラメータを受け取る関数を単一のパラメータ(最初の関数の最初のパラメータ)を受け入れる関数に変換し、新しい関数を返す技術であり、新しい関数は残りのパラメータを受け取り、演算結果を返します.
上記の例では、add(1,2,3,4)をadd(1)(2)(3)(4)に変換することができる.これは部分的な価値観です.毎回入ってくるパラメータは全部私たちが伝えたいパラメータの中の一部です.