thisコンテキストを関数に渡すにはどうすればよいですか?


213

これは簡単にグーグルできるものだと思いましたが、おそらく私は正しい質問をしていません...

特定のJavaScript関数で「this」が参照するものを設定するにはどうすればよいですか?

たとえば、次のようなjQueryのほとんどの関数と同様です。

$(selector).each(function() {
   //$(this) gives me access to whatever selector we're on
});

呼び出されたときに適切な「this」参照を持つ独自のスタンドアロン関数を作成/呼び出すにはどうすればよいですか?私はjQueryを使用しているので、jQuery固有の方法がある場合はそれが理想的です。



私はこれが古い質問であることを知っていますが、ここに上陸する他の人のためにjQueryを参照してください$.proxy
RyBolt

回答:


302

JavaScript .call().apply()メソッドを使用すると、関数のコンテキストを設定できます。

var myfunc = function(){
    alert(this.name);
};

var obj_a = {
    name:  "FOO"
};

var obj_b = {
    name:  "BAR!!"
};

今すぐ呼び出すことができます:

myfunc.call(obj_a);

どちらが警告するでしょうFOO。逆に、通過obj_bすると警告が表示されBAR!!ます。違い.call()とは.apply()つまり.call()、あなたの関数に引数を渡している場合は、カンマが区切りリスト取り、.apply()配列を必要とします。

myfunc.call(obj_a, 1, 2, 3);
myfunc.apply(obj_a, [1, 2, 3]);

したがって、hookこのapply()メソッドを使用すると、関数を簡単に作成できます。たとえば、jQuerys .css()メソッドに機能を追加したいとします。元の関数参照を保存し、カスタムコードで関数を上書きして、保存された関数を呼び出すことができます。

var _css = $.fn.css;
$.fn.css = function(){
   alert('hooked!');
   _css.apply(this, arguments);
};

魔法のargumentsオブジェクトはオブジェクトのような配列なので、に渡すだけapply()です。これにより、すべてのパラメーターが元の関数に渡されることが保証されます。


4
ちょうど楽しい一口:obj_aたとえば、を参照して関数を繰り返し呼び出す必要がある場合は、を使用してそのコピーを作成し、必要に応じてvar boud_myfunc = myfunc.bind(obj_a)呼び出すだけbound_myfunc()です。
wbadart

44

使用function.call

var f = function () { console.log(this); }
f.call(that, arg1, arg2, etc);

関数で使用しthatたいオブジェクトはどこにありますかthis


1
function予約済みキーワードです。function.call(...)は有効なJavaScriptではないため、名前付き関数を含めるように応答を更新することを検討してください。
ダニエルアレン

1
@DanielAllen:私が提供するサンプル関数名を定義しなくても、コードはJSエラーをスローします。しかし、サンプル関数名を更新しました。
palswim 2017

16

jQueryは.call(...)メソッドを使用しthisて、パラメーターとして渡す関数内に現在のノードを割り当てます。

編集:

疑わしい場合は、jQueryのコードの内部を確認してください。すべてが明確で十分に文書化されたJavaScriptに含まれています。

つまり、この質問の答えは574行目あたりです。
callback.call( object[ name ], name, object[ name ] ) === false


12

bind関数を使用してthis、関数内のコンテキストを設定できます。

function myFunc() {
  console.log(this.str)
}
const myContext = {str: "my context"}
const boundFunc = myFunc.bind(myContext);
boundFunc(); // "my context"

12

別の基本的な例:

機能していません:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
};
img.src = reader.result;

ワーキング:

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
}.bind(this);
img.src = reader.result;

だから基本的に:.bind(this)を関数に追加するだけです


これは受け入れられる答えになるはずです。はるかに簡単な構文、はるかに簡単な心...良い仕事Joery
nenea
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.