web-dev-qa-db-ja.com

javascriptで関数のコンテキストを変更する方法

Javascriptで、関数のコンテキストを変更したい理由を理解しようとしています。この手法がどのように/なぜ使用され、その重要性が何であるかを理解するのに役立つ実例または何かを探しています。

このテクニックは、この例を使用して説明されています( http://ejohn.org/apps/learn/#25 から)

var object = {}; 
function fn(){ 
  return this; 
} 
assert( fn() == this, "The context is the global object." ); 
assert( fn.call(object) == object, "The context is changed to a specific object." );
25
32423hjh32423

jQueryはそれをうまく利用しています:

_$('a').each(function() {
    // "this" is an a element - very useful
});
_

実際のjQueryコードは次のようになります。

_for ( name in object ) {
    if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
        break;
    }
}
_

callback( name, object[ name ] )を実行しただけの場合、thisはイテレータ内の現在のオブジェクトに設定されないため、代わりにパラメータを使用する必要があります。基本的にそれは物事を簡単にするだけです。

20
Greg

この例を見てください:

<script>
var el = document.getElementById('button');
el.onclick = function(){
    this.value = "Press Me Again"; //this --> now refers to the the element button not on the window
}

//Another Example:
var Person = function(name,location){
  this.name = name;
  this.location = location;  
  alert(this.location); 
}   
var p2 = new Person("Samantha","California"); //this refers to the instance of the function Person(Person now acts as a class)
var p1 = Person(); // this refers to the window(Person simply acts as a simple function)
</script>
<button id="button1">Press Me</button>

新しいキーワードはコンテキストを変更します。

6
jerjer

私が遭遇した実際の例:

関数をイベントハンドラーとしてDOM要素に追加し、その関数内で「this」を使用する場合、「this」はイベントハンドラーを追加したDOM要素を参照します。

ただし、その関数はオブジェクトのメソッドである可能性があり、その中で使用される「this」キーワードで所有者オブジェクトを参照する必要があるため、「this」となるようにコンテキストを変更する必要があります。"はDOM要素を参照しませんが、所有者オブジェクトを参照します。

Proxy()関数を使用して、jqueryの関数のコンテキストを簡単に変更できます。この質問を参照してください: jquery "this"バインディングの問題(プロトタイプのbindAsEventListenerと同等) そして最初の答え

3
bogdan

AJAXリクエストからのコールバックを行うときに非常に便利です:

function Person(_id, _name) {
    this.id = _id;
    this.name = _name;
};

Person.prototype.sayHi = function(greeting) {
    alert(greeting + " from " + this.name);
};

Person.prototype.loadFromAJAX = function(callback) {
    // in this example, it's jQuery, but could be anything
    var t = this;
    $.get("myurl.php", function(data) {
        callback.call(t, data.greeting);
    });
};

実際、それはかなりくだらない例です。

JQueryではそれをたくさん使用しています。たとえば、jQuery()。get()関数は次のとおりです。

get: function( num ) {
    return num === undefined ?
        // Return a 'clean' array
        Array.prototype.slice.call( this ) :
        // Return just the object
        this[ num ];
}

配列プロトタイプの関数を使用していますが、jQueryオブジェクトのコンテキストで使用しています。

3
nickf

バインド関数はあなたが探しているものかもしれません、バインド関数はあなたが渡したコンテキストで新しい関数を返します、実際のシナリオはあなたがdom要素にいくつかの振る舞いを添付するためにjqueryデリゲートを使用しているときかもしれません別のコンテキストで実行されているコールバック。 'jqueryデルゲートのデフォルトコンテキストはハンドラーにバインドされているdomオブジェクトであるため、domオブジェクトに属するプロパティ以外のプロパティにはアクセスできません。

1
user2639874

setTimeoutを使用するときは、常に異なるコンテキストが必要であり、jQueryには便利な関数 $ .proxy があります。

function iAmCalledAfterTimeout()
{
     alert(this.myProperty); //it will alert "hello world"
}    

setTimeout($.proxy(iAmCalledAfterTimeout, {myProperty:"hello world"}), 1000);
0
algiecas