21

重複の可能性:
Javascript にファーストクラスの関数がある場合、なぜこれが機能しないのですか?

以下のようにエイリアス関数を作成しようとするとdocument.getElementById

f = document.getElementById;

しかし、私が電話しようとすると:

var e_fullname = f(“fullname”);

エラーが発生しました: Could not convert JavaScript argument

以下はOKです:

var e_fullname = f.call(document, “funname”);

なぜか教えてくれますか?

4

3 に答える 3

31

関数を呼び出すには、次の4つの方法があります。

  1. 関数の呼び出し:f(p1, p2)
  2. メソッドの呼び出し:obj.f(p1, p2)
  3. 呼び出しを適用または呼び出す:f.apply(obj, [p1, p2])f.call(obj, p1, p2)
  4. コンストラクターの呼び出し:new f(p1, p2)

これらすべての場合において、は関数オブジェクト(内部プロパティfを持つオブジェクト)への単なる参照(ポインター)です。[[Call]]これらすべての場合で動作が異なるのは、関数の呼び出し方法であり、これは非常に重要です。

したがって、これfはオブジェクトへの単なる参照getElementByIdであり、との間に違いはdocument.getElementByIdありませんsomeOtherHTMLElement.getElementById。関数は、それを参照するオブジェクトへの参照を抑制しません。

特定の「所有者」オブジェクトをバインドする場合は、次のbindメソッドを使用します。

var f = document.getElementById.bind(document);
于 2012-10-21T17:10:16.110 に答える
7

getElementByIdドキュメントのメソッドです。それを呼び出すには、インタープリターは関数本体自体、それを呼び出すオブジェクト(あなたの場合はドキュメント)、および引数を持っている必要があります。

これを行うf = document.getElementByIdと、関数本体をコピーしますが、それを呼び出すオブジェクトはコピーしません。

これを行うとき:

f.call(document, “funname”);

呼び出すオブジェクトと引数の両方を提供します。

fを直接呼び出せるようにする場合は、何らかの方法で「ドキュメント」オブジェクトをそこに格納する必要があります。最も簡単なのは:

var f = function(name){return document.getElementById(name)}

これにより、ドキュメントの価値を保持するクロージャーが作成されます。

bind()を使用して同じことを行うこともできます。

于 2012-10-21T17:04:29.300 に答える
2

あなたが使うことができますbind

呼び出されると、thisキーワードが指定された値に設定され、新しい関数が呼び出されたときに指定された引数の前に指定された引数のシーケンスを持つ新しい関数を作成します。

var f = document.getElementById.bind(document);

ES5で導入されたため、このバージョンのECMAScriptをまだサポートしていないブラウザーに注意してください。

proxy別の方法として、バージョンで追加されたjQueryのメソッドを使用できます1.4

var f = ​$.proxy(document.getElementById, document);

fまたは、独自の関数としてdelcareすることもできます(これはより詳細な解決策です)。

var f = function() { return document.getElementById(arguments); }
于 2012-10-21T17:02:04.150 に答える