2012-01-11 13 views
3

の親オブジェクトを見つける:私は直接randomObject.callBack()を呼び出す場合は、私が機能を持っているコールバック関数

myObject.myFunction = function(callback){ 
    callback(); 
} 

とコールバック

randomObject.callBack = function(){ 
    console.log(this); 
} 

、私はコンソールで親オブジェクトを取得します。しかし、私がmyObject.myFunction(randomObject.callBack)を呼び出すと、DOM要素がログに記録されます。

親オブジェクトにはどのようにアクセスできますか?


私は先に、実行時のコールバックの親オブジェクトの名前を知りません。

答えて

5

オブジェクトのコンテキスト(つまり、this値)は、関数の実行時に決定され、は定義されていないときにはではありません。他の関数にrandomObject.callBackを渡してもコンテキストは送信されません(randomObjectビット)。関数を送信するだけです。

myFunctionが呼び出されたときにコンテキストが設定されている可能性があります。明示的にコンテキストを指定していない(例:callまたはapply)ので、コンテキストはwindowオブジェクトになります。

これを変更するには、実行する前に関数のコンテキストを明示する必要があります。あなたはmyFunctioncallbackを呼び出すときrandomObjectが記録されます、今

myObject.myFunction(randomObject.callBack.bind(randomObject)) 

:あなたはbind方法でこれを行うことができます。

bindは比較的新しいものです。すべてのブラウザでサポートされているわけではありません。上にリンクしたMDNページには、すべてのブラウザで動作するようにするコードがあります。

+0

書き込み時にrandomObjectの名前がわからない場合は、実行時に設定する必要がありますか? –

+0

@MildFuzz私はそれがどうして起こるか分かりません... – lonesomeday

+0

コードは柔軟で、オブジェクトの新しいインスタンスを作成したので書き直す必要はありません。 –

1

あなたがオブジェクトなし機能を呼び出すとき、関数の内部thisは、我々は通常、JavaScriptでこの

myObject.myFunction = function(callback){ 
    callback(); 
} 


randomObject.callBack = function(){ 
    console.log(this); 
} 

function proxyCallback(){ 
    randomObject.callBack(); 
} 

myObject.myFunction(proxyCallback); 
1

のように、thisは、オブジェクトコンテキストを参照するか、これを避けるウィンドウobject.Toを指すようになりますので、これが起こります機能がで、と呼ばれています。これは、が定義されたオブジェクトである必要はありません。です。

関数はオブジェクトのメンバーとして定義されていないものの、オブジェクトのメンバーと呼ばれるように考えることができます。

文脈によってはthisが解決できる4つのことがあります。

  1. 関数呼び出しの前に新しいキーワードがある場合は、新しく作成されたオブジェクト。
  2. 関数が呼び出されたときのドットの左側にあるオブジェクト。
  3. グローバルオブジェクト(通常はウィンドウ)(上記のいずれも指定されていない場合)。
  4. callまたはapply関数に提供される最初の引数。あなたの状況では

、このようなものが適している場合があります:myFunction内、callbackrandomObjectのメンバーとして呼び出されるように

myObject.myFunction(function(){randomObject.callBack()}); 

これはクロージャを作成します。

+1

'.bind'がすべてのルールを上書きする方法を忘れた – Raynos

+0

@Raynos IIRC、' .bind'は、私の例では型のクロージャを作成する単なる関数です。どのように実装されているかによって、ルール2または4に準拠します。間違っていますか? –

+0

'var o = {}; o.foo = f.bind(null); o.foo(); // this === null'。 '.bind'はハードバインドです。 'f.bind(null).call({}); // this === null'。そのバインディングを元に戻すことはできません。 – Raynos

関連する問題