以前に受け入れられた回答は正しくありませんでした。コンストラクターで bind 、 call 、 apply を使用して、新しいコンストラクターを作成できます。テストの唯一の問題は、 bind.apply と bind.call がコンストラクター自体ではなく、 bind.apply とbind.callを適用して呼び出していることを忘れていることです。あなたは間違った議論をしました。
f = Date.bind(null, 2000,0,1)
g = Function.bind.call(Date, null, 2000, 0, 1)
h = Function.bind.apply(Date, [ null, 2000, 0, 1 ])
new f() //=> Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
new g() //=> Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
new h() //=> Sat Jan 01 2000 00:00:00 GMT-0500 (EST)
3人ともinstanceof
伊達です。
Call の引数は、適用する引数が後に続く実行コンテキストです。Apply の引数は、実行コンテキストと引数の配列です。バインドの引数は、バインドする引数が後に続く実行コンテキストです。
たとえば、適用する引数は、bind (Date)を適用するコンテキストと、それに続く bind の引数 である配列です(したがって、最初の配列メンバーは bind のコンテキスト引数です)。これが、バインドの呼び出しまたは適用が混乱する理由です。両方にコンテキスト引数を指定するのは奇妙に感じます。
コンストラクタで bind を使用する場合、'new' は明示的に新しいコンテキストを作成するため、context 引数は常に無視されることに注意してください。それを明確にするためにコンテキスト引数が無関係な場合は null を使用しますが、それは何でもかまいません。
一方、これらの例の apply と call は、bind を適用/呼び出すコンテキストが Date 関数であることを認識する必要があります。可能な場合は「日付」を「関数」に切り替えて、実際にどこでコンテキストを提供しているのかを明らかにしました。Date.bind で apply または call を呼び出すと、実際には、Date オブジェクトにアタッチされていない bind メソッドで apply または call を呼び出しています。このような場合の bind メソッドは、任意の関数から取得できます。Number.bind.call(Date, null, 2000, 0, 1) の場合でも、結果はまったく同じになります。
理由が明らかでない場合は、次の例の違いを検討してください。
context.method();
と
var noLongerAMethod = context.method;
noLongerAMethod();
2 番目のケースでは、メソッドは元のコンテキストから切り離されており (以前にバインドされていない限り)、内部で「this」に依存していた場合は異なる動作をします。特定の関数を直接実行するのではなく、プロパティとしてバインドをプルすると、それは単純に Function.prototype のジェネリック bind メソッドへの別のポインターになります。
個人的には、バインドを呼び出したり適用したりする必要はなかったと思います。それが適切な解決策になる状況を想像するのは難しいですが、コンストラクターをバインドして新しいコンストラクターを作成することは、時々非常に役立つことがわかりました。 . とにかく楽しいパズルです。