「this」変数を簡単に設定しますか?


139

"this"変数を設定する良い方法を理解できないことを除いて、私はJavascriptをかなりよく理解しています。考慮してください:

var myFunction = function(){
    alert(this.foo_variable);
}

var someObj = document.body; //using body as example object
someObj.foo_variable = "hi"; //set foo_variable so it alerts

var old_fn = someObj.fn;   //store old value
someObj.fn = myFunction;   //bind to someObj so "this" keyword works
someObj.fn();              
someObj.fn = old_fn;       //restore old value

最後の4行なしでこれを行う方法はありますか?それはかなり迷惑です...私は匿名関数をバインドしようとしましたが、これは美しくて賢いと思いましたが、役に立ちませんでした:

var myFunction = function(){
    alert(this.foo_variable);
}

var someObj = document.body;        //using body as example object
someObj.foo_variable = "hi";        //set foo_variable so it alerts
someObj.(function(){ fn(); })();    //fail.

明らかに、変数をmyFunctionに渡すことはオプションです...しかし、それはこの質問のポイントではありません。

ありがとう。

回答:


221

JavaScriptのすべての関数に対して定義されている2つのメソッド、、call()およびがありapply()ます。関数の構文は次のようになります。

call( /* object */, /* arguments... */ );
apply(/* object */, /* arguments[] */);

これらの関数は、呼び出された関数を呼び出し、オブジェクトパラメータの値をthisに割り当てます。

var myFunction = function(){
    alert(this.foo_variable);
}
myFunction.call( document.body );

3
また、jQueryを使用$.proxy(function, element)している場合は、その関数が呼び出されるたびに要素のコンテキストになるように使用できます。api.jquery.com/jquery.proxy
Avery

別の.bind()
便利

55

あなたが探していると思います call

myFunction.call(obj, arg1, arg2, ...);

これは myFunctionをにthis設定してobj

apply関数のパラメーターを配列として受け取る、少し異なるメソッドもあります。

myFunction.apply(obj, [arg1, arg2, ...]);

1
ECMAScript言語仕様のセクション15.3.4.3、15.3.4.4および10.1.8を参照してください:ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
一部

18

this値を関数に「保存」して後でシームレスに呼び出すことができるようにする場合(たとえば、その値にアクセスできなくなった場合)、次のことができます。bindます(ただし、すべてのブラウザーで使用できるわけではありません)。

var bound = func.bind(someThisValue);

// ... later on, where someThisValue is not available anymore

bound(); // will call with someThisValue as 'this'

7
FYI bindはIE9 +、FF4 +、Safari 5.1.4+およびChrome 7+ (ソース)で利用できるようです。また、匿名関数に直接バインド呼び出すことができますvar myFunction = function(){ /* this = something */ }.bind(something);
アダム

1

バインドする方法についての私の検索 thisが私をここにもたらしたので、私の発見を投稿します。「ECMAScript 2015」では、矢印関数を使用してこれを字句的に設定することもできます。

参照:https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

の代わりに:

function Person() {
  setInterval(function growUp() {
    // The callback refers to the `self` variable of which
    // the value is the expected object.
    this.age++;
  }.bind(this), 1000);
}

これで次のことができます。

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();

0

の設定 thisJavaScriptでキーワードをます。

JavaScriptには、thisキーワードを簡単に設定するための3つの組み込みメソッドがあります。それらはすべてFunction.prototypeオブジェクト上にあるため、すべての関数がそれらを使用できます(すべての関数がプロトタイプの継承を介してこのプロトタイプから継承されるため)。これらの関数は次のとおりです。

  1. Function.prototype.call():この関数は、使用するオブジェクトをthis最初の引数として受け取ります。次に、残りの引数は、呼び出される関数のそれぞれの引数です。
  2. Function.prototype.apply():この関数は、使用するオブジェクトをthis最初の引数として受け取ります。次に、2番目の引数は、呼び出される関数の引数の値を含む配列です(配列の最初の要素は関数の最初の引数、配列の2番目の引数は関数の2番目の引数など)。
  3. Function.prototype.bind():この関数は、の値が異なる新しい関数を返しますthisthis値として設定したいオブジェクトを最初の引数として取り、新しい関数オブジェクトを返します。

呼び出し/適用とバインドの違い:

  • call そして apply、関数すぐに呼び出すという点で類似しています(事前定義された値this)。
  • bindとは異なりcallapply、この機能があるという事実で新しい関数を返すの結合異なるとthis値。

例:

const thisObj = {
  prop1: 1,
  prop2: 2,
};

function myFunc(arg1, arg2) {
  console.log(this.prop1, this.prop2);
  console.log(arg1, arg2);
}

// first arg this obj, other arguments are the  
// respective arguments of the function
myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');

// first arg this obj, other argument is an array which  
// are the respective arguments of the function
myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);


// the bind method returns a new function with a different
// this context which is stored in the newMyFunc variable
const newMyFunc = myFunc.bind(thisObj);

// now we can call the function like a normal function 
newMyFunc('first', 'second');

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.