32

この関数に頭を巻くのに問題があります。

var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]​​​​​​​​​​​​​​​​​​​​​​​​​​​

2行目にあるように、この関数はどのように引数を受け入れますか?

4

7 に答える 7

31

上手、

  • Function.prototype.callthis選択した値で関数を呼び出すために使用される「call」関数を参照します。
  • 後続.bindは、関数プロトタイプの「bind」関数を参照します(「call」も関数であることを忘れないでください)。これはthis、渡された引数に常に設定される新しい関数を返します。
  • 「bind」に渡される引数はObjectプロトタイプの「toString」関数であるため、その式全体の結果はthis、「toString」関数に設定された「call」関数を実行する新しい関数になります。

したがって、結果は次のようになりますObject.prototype.toString.call( param )。次に、「console.log」呼び出しがその関数に配列を渡し、そこにそれがあります。

編集「param」がオブジェクトである場合、それは実際のObject.prototype.toString.call( param )ようであることに注意してください。param.toString()そうでない場合、「呼び出し」関数のセマンティクスは、JavaScriptが行う通常の方法(数値->数値、文字列->文字列など)で関数を1つに変換することです。

編集、2016年5月24日—上記の最後の文はES2015では正確ではありません。新しいJavaScriptランタイムは、プリミティブ型が値として関数呼び出しに関与している場合、それらを「自動ボックス化」しませthis

于 2012-06-20T14:20:02.003 に答える
10

私はあなたがすでに何を知っていて何をしている.call.bind思います

toStrこれで、基本的に次のことを行う関数になりました。

function toStr( obj ) {
    return Function.prototype.call.call( Object.prototype.toString, obj );
}

IE.call.call、コンテキスト引数が関数に設定された.toString関数です。.call通常、関数をのコンテキストとして設定する関数のプロパティとして使用するため、通常、その部分はすでに処理されています.call

于 2012-06-20T14:20:18.650 に答える
3

2行のコードは、関数定義と、空の配列が内部に渡されたその定義の実行呼び出しです。複雑さは、「これ」が何を指しているのか、そしてその理由を解釈することにあります。

この値を推測するために、以下の2つのリンクからMDNの呼び出しとバインドの定義にコンテンツをコピーしました。

bind()関数は、呼び出されている関数(バインドされた関数のターゲット関数)と同じ関数本体を持ち、この値がbind()の最初の引数にバインドされた新しい関数(バインドされた関数)を作成します。コードは、バインドページで説明されている「ショートカット関数」に似ています。

var unboundSlice = Array.prototype.slice; // same as "slice" in the previous example
var slice = Function.prototype.call.bind(unboundSlice);

//..。

スライス(引数);

callを使用すると、既存の関数を呼び出すときに別のこのオブジェクトを割り当てることができます。これは、現在のオブジェクトである呼び出し元オブジェクトを参照します。呼び出しを使用すると、メソッドを一度記述してから、新しいオブジェクトのメソッドを書き直すことなく、別のオブジェクトに継承できます。

toStrが呼び出されると、バインドする配列が渡され、このポインターがバインドされます。bind()を使用すると、これを簡略化できます。

toStr() is a bound function to the call() function of Function.prototype, with the this value set to the toStr() function of Array.prototype. This means that additional call() calls can be eliminated

本質的には、toStringメソッドへのショートカット関数のオーバーライドのように見えます。

于 2012-06-20T14:33:51.080 に答える
2

bind() -呼び出されると、指定されたこの値のコンテキストでこの関数を呼び出す新しい関数を作成します。新しい関数が呼び出されたときに指定された引数の前に、指定された引数のシーケンスがあります。

JavaScriptのbind()の詳細については、このドキュメントをお読みください

角度のある例:

定義された関数があり、それをオブジェクトにバインドする親コンポーネント:

public callback: object;

constructor() {
    this.callback= this.myFunction.bind(this);
}

public myFunction($event: any) {
    // Do something with $event ...
}

(親html)バインドされたオブジェクトを子コンポーネントに渡す:

<child-component (callbackFunction)="callback($event)"></child-component>

親関数にバインドされているオブジェクトを受け取る子コンポーネント:

@Output() callbackFunction: EventEmitter<object> = new EventEmitter<object>();

public childFunction() {
    ...
    this.callbackFunction.emit({ message: 'Hello!' });
    ...
}
于 2012-06-20T14:22:32.517 に答える
2

JSから英語への翻訳-

var toStr = Function.prototype.call.bind(Object.prototype.toString);

はのbind新しいcall関数を作成しObject.prototype.toStringます。

これで、に適用される任意のコンテキストでこの新しい関数を呼び出すことができますObject.prototype.toString

このような:

toStr([]) // [object Array]​​​​​​​​​​​​​​​​​​​​​​​​​

なぜ電話しないのですObject.prototype.toString.call([])か?

答え:

もちろん、できます。ただし、OPsメソッドは、この目的のためだけに、専用の非メソッド化関数を作成します。

これは実際には非方法化と呼ばれます。

于 2018-04-05T16:13:14.963 に答える
1

あなたができる:

var toStr = Object.prototype.toString.call([]);

これに関する問題は次のとおりです。呼び出しは即座に実行されます。必要なのは、呼び出しの実行を遅らせることです。

*関数はJavascriptでもオブジェクトであるため、オブジェクトを最初の引数として渡す代わりに、' call 'の最初の引数として任意の関数を使用できます。*また、他のオブジェクトと同様に、呼び出し時にドットを使用できます。

Function.prototype.call.bind(Object.prototype.toString)は、' this 'をObject.prototype.toStringに設定して呼び出し関数のコピーを作成します。この新しい呼び出し関数のコピーを「toStr」に保持します。

var toStr = Function.prototype.call.bind( Object.prototype.toString );

これで、「this」はすでにObject.prototype.toStringにバインドされているため、「this」を設定しなくても、いつでもこの新しい呼び出しのコピーを実行できます。

于 2018-06-15T11:40:34.983 に答える
1
  1. これはあなたにとって理にかなっているはずです
Object.prototype.toString.call([]) //work well
  1. このフォームは長すぎて面倒だと思いますが、単純化したいですか?これにより、後で使いやすくなります。
const toStr = Object.prototype.toString.call
toStr([]) // unfortunately, this does not work
  1. bindを使用して、ポイントがどこを指すかを修正する必要がありますthis
const toStr = Object.prototype.toString.call.bind(Object.prototype.toString)
toStr([]) //work well
  1. Object.prototype.toString.callと同じですFunction.prototype.call
const toStr = Function.prototype.call.bind(Object.prototype.toString)
toStr([]) //done

まとめ

function f(){console.log(this, arguments)}

f.callと同じですFunction.prototype.call.bind(f)

f.call(1,2,3)と同じですFunction.prototype.call.bind(f,1)(2,3)

于 2021-04-28T12:15:28.993 に答える