以下は uncurring の 2 つの実装です
1を達成
リーリー2を達成
リーリー2 つの結果は同じですが、主にここで 2 番目の実装方法について少し混乱しています
リーリーすぐにクリックされました、ありがとうございます!
リーリールイザイ
我想大声告诉你2017-05-16 13:43:58
Function.prototype.call.apply(self, arguments);
これは少し複雑に見えるかもしれませんが、実際には理解するのは簡単です。
実際、2 番目の実装は、アンチカリーの 3 番目の実装につながる可能性もあります。
リーリー
リーリー
uncurrying
を呼び出す人は、this
または self
と等しくなります。これは、self
が 配列であることを意味します。 Push メソッド
。 self
を置き換え、最後の外部 push
は次の関数と同等です:uncurrying
,谁就等于this
或self
. 这意味着self
就是数组的push方法
.
替换掉self
,最终外部的push
リーリー
ここに
には配列をパラメータに分解する機能があることを理解しましょう。 apply
函数,apply
導出式:a.apply(b, arguments)
意味着把b当做this上下文,相当于是在b上调用a方法,并且传入所有的参数,如果b中本身就含有a方法,那么就相当于 b.a(arg1, arg2,…)
式 1:a.apply(b, arguments) === b.a(arg1, arg2,…)
call
和 apply
:
a.call(b, arg) === b.a(arg)
式 1
つまり、a は call メソッドと同じです。
次に数式を代入すると、次のようになります: a = Function.prototype.call
つまり、b は配列のプッシュメソッドと同じです
すると、b = Array.prototype.push
は次と相対関係になります:
Function.prototype.call.apply(Array.prototype.push, arguments)
、それでは:
Array.prototype.push.call(arg1, arg2,…)
を
に代入します。これは次と同等です: push([], 1)
就相当于 Array.prototype.push.call([], 1)
答えはすでに明らかで、配列の末尾に数値 1 を追加することです。 [].push(1)
の場合、全体は次と同等です:
this.call.bind(this);
部分,this
相当于Array.prototype.push
理解したいなら、複雑なことを単純化する必要があります。理解するのが簡単であればあるほど、より深く理解できるようになります。 Array.prototype.push.call.bind(Array.prototype.push)
をさらに単純化するには、新しい関数を返すだけです。
関数
がパラメーターをバインドし、最終的に以下を返すと仮定します。
リーリー
bind
的原理,等同于谁调用bind
上記は
Array.prototype.push.call.bind(Array.prototype.push)
は次と同等になります:
これは、アンチカリーの 2 番目の実装とは少し異なりますが、表面的には一貫性がないように見えますが、本質的には一貫しています。しばらくお待ちください。以下をお読みください:
違いは前半のArray.prototype.push.call
,这里它是一个整体,实际上想代表的就是call方法。而我们都知道,所有函数的call方法,最终都是Function.prototype
的 call
方法にあります。この場合、次の恒等式が成り立ちます:
上記の関数は次と同等になります:
リーリー置換されたパラメータを削除すると、関数は次のように復元できます:
リーリー要約すると、アンチカリーの最後の 3 番目の実装は 2 番目の実装と完全に一致します。 気に入っていただけましたら、ぜひ「いいね」を押して、ありがとうございます~
。とカレーについての理解を深めるために、それらを深く分析するブログも書きました。 bind
気に入った学生は、私のコラム Lewis のフロントエンド詳細コースもフォローしてください
淡淡烟草味2017-05-16 13:43:58
基本
callとapplyの違いや機能については詳しく説明しません
ソースコード実装の呼び出しと適用
ここでは、呼び出しのみを紹介します。例: a.call(b, c)
最初のパラメータ x = b を取り出します {}
x.fn = a
最初のパラメータを除くパラメータをカンマで区切って結合すると、結果は d
独立した実行環境で関数 e = new Function() を作成し、関数内で x.fn(d) を実行します
作成したeを実行
解決策 2 の理解
オブジェクト メソッドを展開するための call と apply の問題はここでは考慮しません。メソッドはソース コードから動的に作成されるため、この問題については以下で詳しく説明しません。
self は Array.prototype.push を指します
(Function.prototype.call).apply(Array.prototype.push, 引数);
先ほど説明したソース コードを使用して 2 を変換し、Array.prototype.push.(Function.prototype.call)(arguments) を取得します。ここでも呼び出しは配列ではなく変換される必要があります。4 を参照してください。
arguments は配列のようなオブジェクト [arr, 1] です。3 を変換して Array.prototype.push.(Function.prototype.call)(arr, 1) を取得します
callのソースコードは説明されているので、4を変更してarr.(Array.prototype.push)(1)を取得します
もっと詳しく書いてください、arr.push(1)